language-agnostic graph code-golf rosetta-stone

language agnostic - CodeGolf: encuentra los caminos únicos



language-agnostic graph (9)

Aquí hay una idea bastante simple, en este pastebin he publicado algunos pares de números. Estos representan los nodos de un grafo dirigido. La entrada a stdin será de la forma, (serán números, usaré un ejemplo aquí)

c d q r a b b c d e p q

entonces xy significa que x está conectado a y ( no viceversa)

Hay 2 caminos en ese ejemplo. a->b->c->d->e y p->q->r .

Debe imprimir todas las rutas únicas de ese gráfico. La salida debe ser del formato.

a->b->c->d->e p->q->r

Notas

  1. Puede asumir que los números se eligen de manera que una ruta no se interseca con la otra (un nodo pertenece a una ruta)
  2. Los pares están en orden aleatorio.
  3. Son más de 1 caminos, pueden ser de diferentes longitudes.
  4. Todos los números son menos de 1000.

Si necesita más detalles, por favor deje un comentario. Voy a enmendar según sea necesario.

Enchufe descarado

Para aquellos que disfrutan de Codegolf, por favor Comprométase en Area51 por su propio sitio :) (para aquellos que no lo disfruten, por favor apóyelo, así que nos mantendremos fuera de su camino ...)


Ocaml

402 caracteres

Básicamente una adaptación de la versión de Haskell, cuya longitud me sorprende. Ciertamente hay una manera de hacerlo mejor con Str y / o la sintaxis revisada .

open List;;open String;; let q(a,b,p)=print_string(p^b^"/n")in let rec f(a,b,p)=function []->[a,b,p]|(x,y,q)::l when x=b->f(a,y,p^q)l|(x,y,q)::l when y=a->f(x,b,q^p)l|h::t->h::(f(a,b,p)t)in let t s=let i=index s '' ''in let h=sub s 0 i in h,sub s (i+1) ((length s) -i-1),h^"->"in let s=ref []in try while true do let l=read_line ()in s:=l::!s done with End_of_file->List.iter q(fold_right f(map t !s)[])

Ungolfed

open List;; open String;; let print (a,b,p) = print_string (p^b^"/n") in let rec compose (a,b,p) = function [] -> [a,b,p] |(x,y,q)::l when x=b->compose (a,y,p^q) l |(x,y,q)::l when y=a->compose (x,b,q^p) l |h::t->h::(compose(a,b,p) t) in let tokenize s = let i = index s '' '' in let h = sub s 0 i in h,sub s (i+1) ((length s) -i-1),h^"->" in let lines = ref [] in try while true do let l = read_line () in lines := l::!lines done with End_of_file-> List.iter print (fold_right compose (map tokenize !lines) [])


PHP - 155

foreach(file($argv[1])as$x){$x=explode('' '',$x);$g[$x[0]+0]=$x[1]+0;} foreach($g as$a=>$b)if(!in_array($a,$g)){echo$a;while($b=$g[$b])echo"->$b";echo"/n";}

Todo el archivo se ve como:

<?php error_reporting(0); foreach(file($argv[1])as$x){$x=explode('' '',$x);$g[$x[0]+0]=$x[1]+0;} foreach($g as$a=>$b)if(!in_array($a,$g)){echo$a;while($b=$g[$b])echo"->$b";echo"/n";}

Correr:

$ php graph.php graph.txt

Versión bonita:

$lines = file($argv[1]); foreach ($lines as $line) { $vertexes = explode('' '',$line); $graph[$vertexes[0]+0] = $vertexes[1]+0; // the +0 forces it to an integer } foreach ($graph as $a => $b) { //searches the vertexes that are pointed to for $a if (!in_array($a,$graph)) { echo $a; for ($next = $b; isset($graph[$next]); $next = $graph[$next]) { echo "->$next"; } //because the loop doesn''t run one last time, like in the golfed version echo "->$next/n"; } }


Pitón

120 caracteres

Me gusta lo fácil que se lee en Python:

import sys d=dict(map(str.split,sys.stdin)) for e in set(d)-set(d.values()): while e in d:print e,''->'',;e=d[e] print e

Y el resultado de correr sobre la muestra de pasta-bin:

784 -> 955 -> 381 -> 231 -> 76 -> 644 -> 380 -> 861 -> 522 -> 775 -> 565 -> 773 -> 188 -> 531 -> 219 -> 755 -> 247 -> 92 -> 723 -> 726 -> 606 821 -> 238 -> 745 -> 504 -> 99 -> 368 -> 412 -> 142 -> 921 -> 468 -> 315 -> 193 -> 674 -> 793 -> 673 -> 405 -> 185 -> 257 -> 21 -> 212 -> 783 -> 481 -> 269 477 -> 4 -> 470 -> 350 -> 401 -> 195 -> 258 -> 942 -> 263 -> 90 -> 716 -> 514 -> 110 -> 859 -> 976 -> 104 -> 119 -> 592 -> 968 -> 833 -> 731 -> 489 -> 364 -> 847 -> 727


C89 - 212 204 caracteres

#define M 1001 int t[M],r[M],a,b;main(){while(scanf("%d%d",&a,&b)>0)t[a+1]=r[a+1]=b+1; for(a=1;a<M;a++)r[t[a]]=0;for(a=1;a<M;a++)if(r[a]){printf("%d",a-1); for(b=t[a];b;b=t[b])printf("->%d",b-1);puts("");}}

No se cuentan las nuevas líneas innecesarias.

Mando:

$ wget -O - http://pastebin.com/download.php?i=R2PDGb2w | ./unique-paths

Salida:

477->4->470->350->401->195->258->942->263->90->716->514->110->859->976->104->119->592->968->833->731->489->364->847->727 784->955->381->231->76->644->380->861->522->775->565->773->188->531->219->755->247->92->723->726->606 821->238->745->504->99->368->412->142->921->468->315->193->674->793->673->405->185->257->21->212->783->481->269

Versión bonita:

#include <stdio.h> int main(void) { /* Note: {0} initializes all items to zero. */ int target[1001] = {0}; /* If a → b, then target[a+1] == b+1. */ int root[1001] = {0}; /* If a is a root, then root[a+1] != 0. */ int a, b, i, next; /* Read input numbers, setting the target of each node. Also, mark each source node as a root. */ while (scanf("%d %d", &a, &b) == 2) target[a+1] = root[a+1] = b+1; /* Mark each node that is pointed to as not a root. */ for (i = 1; i <= 1000; i++) root[target[i]] = 0; /* For each root node, print its chain. */ for (i = 1; i <= 1000; i++) { if (root[i] != 0) { printf("%d", i-1); for (next = target[i]; next != 0; next = target[next]) printf("->%d", next-1); printf("/n"); } } return 0; }


Haskell - 174 142 137 133 caracteres

import List a#m=maybe[](/x->"->"++x++x#m)$lookup a m q[f,s]=f//s>>=(/a->a++a#zip f s++"/n") main=interact$q.transpose.map words.lines

Ungolfed

import Data.List type Node = String follow :: Node -> [(Node,Node)] -> String follow node pairs = maybe "" step $ lookup node pairs where step next = "->" ++ next ++ follow next pairs chains :: [[Node]] -> String chains [firsts,seconds] = concatMap chain $ firsts // seconds where chain node = node ++ follow node pairs ++ "/n" pairs = zip firsts seconds process :: [String] -> String process = chains . transpose . map words main :: IO () main=interact $ process . lines

Enfoque menos elegante que antes, pero más corto! Inspirado por la idea de Nas Banov de h.keys-h.values


Ruby - 132 125 87

h=Hash[a=[*$<].map(&:split)] 1000.times{a.map!{|i|i+[h[i[-1]]]-[nil]}} puts a.sort_by{|i|-i.size}.uniq(&:last).map{|i|i*''->''}

Tomó la idea de h.keys-h.values Nas Banov:

h=Hash[[*$<].map &:split] puts (h.keys-h.values).map{|i|s=i s+=''->''+i=h[i]while h[i];s}


Aunque no es la respuesta, el siguiente script de Linux dibuja un gráfico del archivo de entrada:

cat FILE | (echo "digraph G {"; awk ''{print "/t" $1 "-> " $2;}''; echo "}") / | dot -Tpng > out.png && eog out.png

Necesitará Graphviz instalado para el comando dot , y eog es el visor de imágenes de GNOME .

Ejecutar en el archivo de entrada, el gráfico se ve así:

Girado 90 ° y reducido ( )

Como puede ver, el gráfico de entrada es solo una colección de listas enlazadas individualmente sin nodos compartidos ni ciclos.


Lua, 166 bytes

Ow sí, finalmente un codegolf donde Lua no apesta. Producto adicional: funciona en cualquier cosa que esté separada por espacios (números de cualquier tamaño, cadenas, ...)

La versión sin golf:

-- Read in a file from stdout filled with pairs of numbers representing nodes of a (single-)directed graph. -- x y means x->y (but not y->x) g={}t={}w=io.write i=io.read"*a" -- read in numbers from stdin for x,y in i:gmatch"(%w+) (%w+)" do -- parse pairs t[y]=1 -- add y to destinations (which never can be a starting point) g[x]=y end for k,v in pairs(g) do -- go through all links if not t[k] then -- only start on starting points w(k) -- write the startingpoint while v do -- as long as there is a destination ... w(''->'',v) -- write link v=g[v] -- next destination end w''/n'' end end

La versión de golf:

g={}t={}w=io.write for x,y in io.read"*a":gmatch"(%w+) (%w+)"do t[y]=1 g[x]=y end for k,v in pairs(g)do if not t[k]then w(k)while v do w(''->'',v)v=g[v]end w''/n''end end


Java

372 337 304 bytes

Actualización :

  1. Genéricos removidos. Y al parecer, la clase puede prescindir de ser "público" (Thnx Sean)
  2. Clase eliminada, reemplazado por Enum. (Ver comentarios, Thnx Nabb)

import java.util.*;enum M{M;{Scanner s=new Scanner(System.in);final Map g=new HashMap();while(s.hasNext()){g.put(s.nextInt(),s.nextInt());}for(int a:new HashSet<Integer>(g.keySet()){{removeAll(g.values());}}){while(g.containsKey(a)){System.out.print(a+"->");a=(Integer)g.get(a);}System.out.println(a);}}}