Dos caminos divergieron en un bosque amarillo (parte 2)


25

Este es el segundo de una serie, el tercero es Dos caminos divergidos en un bosque amarillo (parte 3)

Esto se basa en dos caminos divergidos en un bosque amarillo (parte 1) , un desafío previo mío. Fue bastante bien recibido, pero también fue bastante trivial (¡una respuesta de Java en 52 bytes!) Así que hice algo más complejo ...

La inspiración

Este desafío está inspirado en el famoso poema de Robert Frost, "The Road Not Taken":

Dos caminos se bifurcaban en un bosque amarillo,
y lo siento, no podía viajar a la vez,
y ser un viajero, me quedé parado
y miré hacia abajo lo más lejos que pude,
hacia donde se doblaba en la maleza;

... 2 párrafos recortados ...

Voy a decir esto con un suspiro
En algún lugar de siglos en adelante:
dos caminos divergieron en un bosque, y yo
... tomé el menos transitado,
y eso ha marcado la diferencia.

Observe la penúltima línea I took the one less traveled by,,. Su objetivo es encontrar el camino menos transitado en su entrada de cadena. Debe generar uno de los 2 valores que son distintos entre sí que indican en qué dirección debe girar para tomar el camino menos transitado. Una vez que la carretera se bifurca (el rastro de los hexágonos cambia a números) estás en la intersección. A partir de ahí, habrá 2 caminos formados por dígitos. El camino cuyos dígitos tienen la suma más baja será el camino no tomado. Tenga en cuenta que el camino no tomado puede tener una ruta más grande pero una suma de ruta más baja. Aquí hay algunos ejemplos / casos de prueba de un programa que imprime "izquierda" o "derecha" para la ruta no tomada:

 1     2
  1   2
   1 2
    #
    #
    #
left (3 < 6)


 1     2
  2   2
   1 1
    #
    #
    #
left (4 < 5)


 12    2
  11  2
   1 1
    #
    #
    #
right (6 > 5)


 99   989
  99  89
  99 99
  99 99
    #
    #
    #
   # 
left (72 < 79)


1111 1110
 001 111
  11 11
  11 11
    #
   ##
  ##
 ##  
left (9 < 10) (Note: 1111 is interpreted as 1+1+1+1=4, not 1111=1111)


1       1
 0     1
  1   1
  1   1
  1   1
  1   1
   1 1 
    #
    #
    #
     #
      #
left (6 < 7)


1   1 
 0   1  
  1   1
  1   1
  1   1
  1   1
   1 1 
    #
    #
    #
     #
      #
left (6 < 7)

Cosas para asumir y recordar

  • Siempre habrá 2 caminos. Ni mas ni menos.
  • Puede tomar la entrada de STDIN una línea a la vez, una cadena que contiene caracteres LF o una cadena que contiene una barra diagonal inversa y una n. Si necesita información de alguna otra manera, solicite aprobación en los comentarios.
  • No tiene que preocuparse por entradas no válidas o rutas vinculadas. Esos nunca serán ingresados ​​a su programa / función.
  • La entrada puede ser de cualquier longitud en ancho o alto, menor que el límite de cadena de su idioma.
  • Nunca habrá un #y un número en la misma línea.
  • Todos los dígitos en la ruta son enteros positivos de 0 a 9.
  • Se permite la entrada o salida con una nueva línea final.
  • Vea mi respuesta JS ES6 a continuación para ver un ejemplo.
  • Siempre habrá al menos 1 espacio entre las 2 rutas.
  • Las 2 rutas siempre tendrán la misma altura para cada mapa, pero pueden ser diferentes en otros mapas.
  • Si está confundido acerca de un caso de prueba específico, dígamelo.
  • 1111 se interpreta como 1 + 1 + 1 + 1 = 4, no 1111 = 1111. El mapa es una serie de números de un dígito, no números de longitud arbitraria.
  • Este es el , por lo que gana la respuesta más corta en bytes.
  • Lagunas estándar prohibidas

Si tiene alguna pregunta sobre este desafío, pregúnteme en los comentarios y ¡buena suerte!


¡Hola, puedes ver todas las respuestas y su número de bytes pegando $("div > h1").map(function(){return $(this).text()}).get().join("\n");en tu consola!
programador

1
Aquí hay una versión alternativa con espacios en blanco eliminados e ignoradas respuestas tachadaslet answers = $('div > h1').map(function(){return $(this).clone().children(':not(a)').remove().end().text().replace(/\s+/g,' ').trim()}).get();answers.splice(0, 1);answers.join('\n');
David Archibald

2
Un # no es un hexágono ...
user253751

1
" pero también fue bastante trivial (¡una respuesta de Java en 52 bytes!) " 43 bytes ahora. ;)
Kevin Cruijssen

¿Cerrar los votos de nuevo? ¿Qué demonios te pasa?
Matthew Roh

Respuestas:


2

05AB1E , 21 15 bytes

Salidas 0 para izquierda y 1 para derecha.

|vy#õK€SO})øO`›

Pruébalo en línea!

Explicación

|v                # for each line in input
  y#              # split on spaces
    õK            # remove empty strings
      €S          # split each string into a list of chars
        O         # sum each sublist
         }        # end loop
          )ø      # wrap stack in a list and zip
            O     # sum each sublist (side of the tree)
             `›   # compare left to right

11

Retina , 28 bytes

\d
$*
%r`1\G
-
Os`.
+`-1

1+

Pruébalo en línea!

Imprime 0para izquierda y 1para derecha. Asume que no hay espacios finales en ninguna línea.

Explicación

\d
$*

Convierte cada dígito Nen una serie de Nunidades.

%r`1\G
-

Una en cada línea ( %), haga coincidir las consecutivas ( \G) desde el final ( r) y reemplace cada una de ellas con -(es decir, convierta la rama derecha en -s).

Os`.

Ordene todos los caracteres, de modo que todos los -s estén directamente delante de todos los 1s.

+`-1

Repetidamente cancelar un par de -y 1.

1+

Intente hacer coincidir al menos uno 1(si es así, había más pesos en el camino izquierdo).



7

Chip , 216 bytes

 EZ,Z~.
E~]x-.|
F].>vm'
Ax]}#----------------.
Bx]}#---------------.|z.
Cx]}#------------.,Z|##' E
Dx]}#---------.,Z|`@@('A~^~t
 E.>#------.,Z|`@@-('
A~S`#v--.,Z|`@@-('
*f,--<,Z|`@@-('
e |,Z|`@@-('
,Z|`@@-('
>@@-('
a

Pruébalo en línea!

Un poco más grande que la respuesta para la parte 1 ...

Visión general

Chip es un lenguaje 2D inspirado en los circuitos reales, y trata con los bits componentes de cada byte en una secuencia de bytes.

Esta solución mantiene una suma continua de los dígitos que ve, cambiando el signo de la entrada cada vez que encuentra un tramo de espacio en blanco, y luego termina con el primero #. Entonces, para entrada

 11   12
  2   2
   1 1
    #
    #
    #

Nosotros conseguimos 1 + 1 - 1 - 2 + 2 - 2 + 1 - 1 = -1. El signo del resultado se da como salida, un número negativo produce el resultado 1y positivo es 0.

Por lo tanto, la salida de 1significa que el camino izquierdo se toma menos y 0significa derecho.

Explicación

A un alto nivel, así es como funciona:

La diagonal principal con los @elementos es el acumulador, la salida se decide aen la parte inferior. (Ocho pares de@ medias significa ocho bits, pero el bit más alto es el signo, por lo que esta solución puede manejar una diferencia máxima de +127 o -128. Desbordarse a la mitad está bien, siempre y cuando regresemos antes de terminar).

Las cuatro líneas que comienzan como Ax]}#--... son leer la entrada y, en el caso de un dígito, negarla (si es necesario) y pasar el valor a los sumadores.

Las primeras tres líneas deciden si estamos viendo un dígito o una secuencia de espacios en blanco, y hacen un seguimiento de si los dígitos deben ser negados.

Los elementos restantes encajados debajo de las entradas y los elementos en el extremo derecho manejan la condición de terminación, y asignan la salida a ASCII (para que obtengamos caracteres '0'o en '1'lugar de valores 0x0o 0x1. Esta asignación ASCII no requiere bytes adicionales, de lo contrario no lo haría lo he incluido)


2
Me gusta que el código se parezca a dos caminos divergentes.
Laikoni

@Laikoni ni siquiera me había dado cuenta, eso es genial :)
Phlarx

4

JavaScript (ES6), 55 bytes

x=>x.replace(/\d(?=.*( )|)/g,(d,s)=>t-=s?d:-d,t=0)&&t<0

Asume que no hay espacios finales en cada línea y salidas truepara right, falsepara left. El truco consiste en hacer coincidir cada dígito en la entrada, y si hay un espacio después en la misma línea, restarlo del total; de lo contrario, agréguelo al total. Si el total final es menor que 0, el camino correcto es el que menos transitado, y viceversa.

Pruébalo:

f=x=>x.replace(/\d(?=.*( )|)/g,(d,s)=>t-=s?d:-d,t=0)&&t<0
<textarea placeholder = "paste in a map here..." oninput = "document.querySelector('div').innerText = f(this.value)"></textarea>
<div></div>


Debe poner un x=al principio, porque las expresiones no están permitidas, solo las funciones se almacenan como una variable y programas completos.
programador

@ programmer5000 ¿Por qué? Parece un poco extraño anular los valores predeterminados y no parece indicar que este sea el caso en la pregunta.
Wheat Wizard

1
@ programmer5000 En realidad, las funciones sin nombre están permitidas por defecto . (Gracias por el fragmento, por cierto)
ETHproductions

4

Python 3 , 85 94 bytes

import re
g=lambda s,i:sum(map(int,''.join(re.findall('\d+',s)[i::2])))
lambda s:g(s,0)>g(s,1)

Pruébalo en línea!

Maldiciones! No leí el problema lo suficientemente cerca. Se agregó un arreglo ( ''.join()), pero a un costo de 9 bytes.


¡Tan cerca! Buena captura, gracias!
Datastream


2

Retina , 180 bytes

El recuento de bytes asume la codificación ISO 8859-1.

^(?=( *(0|(1|(?<3>2|(?<3>3|(?<3>4|(?<3>5|(?<3>6|(?<3>7|(?<3>8|(?<3>9))))))))))+.+¶)+)(.+ (0|(?<-3>1|(?<-3>2|(?<-3>3|(?<-3>4|(?<-3>5|(?<-3>6|(?<-3>7|(?<-3>8|(?<-3>9))))))))))+¶)+ *#

Pruébalo en línea!

Pensé que también probaría una solución solo de expresiones regulares (lo anterior es una expresión regular de .NET que coincide solo con las entradas donde se debe tomar la ruta correcta, excepto para usar como una abreviatura de \n).

Es molestamente repetitivo, pero eso es lo que sucede cuando tienes que tratar cada posible dígito individualmente.

La solución es una aplicación bastante sencilla de grupos de equilibrio : primero sumamos los dígitos en la rama izquierda empujando las Ncapturas en la pila 3para cada dígito N. Luego intentamos alcanzar el #, mientras emergemos de los 3 Ntiempos de pila para cada dígito Nen la rama derecha. Esto solo es posible si la suma de dígitos en la rama izquierda es mayor que la de la rama derecha (ya que no puede aparecer desde una pila vacía).


No estoy familiarizado con las expresiones regulares .NET, pero ¿no puedes hacer un conjunto de caracteres: [0-9]para que coincida con todos los dígitos o \d?
programmer5000

@ programmer5000 Por supuesto, pero no puedo distinguir entre ellos para determinar cuántas capturas debo empujar para sumarlas.
Martin Ender

2

JavaScript (ES6), 106104 bytes

s=b=>(b=b.split`\n`,c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)

s=b=>(b=b.split("\n"),c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)

ses una función que regresa truesi el camino no tomado está a la izquierda. Sin golf:

var proc = function(str){
    str = str.split("\n");
    var left = 0;
    var right = 0;
    str.forEach(item=>{
        var match = item.match(/\d+/g) || [];
        console.log(match);
        left += +(match[0] ? match[0] : 0);
        right += +(match[1] ? match[1] : 0);
    });
    return left < right;
};

s=b=>(b=b.split`\n`,c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)
<textarea placeholder = "paste in a map here..." oninput = "document.querySelector('div').innerText = s(this.value)"></textarea>
<div></div>


Espero que alguien pueda obtener un mejor puntaje que este ...
programmer5000

Reto aceptado @ programmer5000
David Archibald

@DavidArchibald alguien ya lo hizo, pero agradecería una nueva respuesta. ¿Estás interesado en el tercero de la serie ?
programador

seguro. No me di cuenta de que había 3
David Archibald

2

PowerShell , 80 bytes

$args-split'\s|#'-ne''|%{$a+=(($i=[char[]]$_-join'+'|iex),-$i)[($x=!$x)]};$a-gt0

Pruébalo en línea!

(Solo chirriando bajo las respuestas de Python.: D)

Salidas Truepara la ruta izquierda y Falsepara la ruta derecha.

Toma la entrada como una cadena delineada con `n , que es el equivalente de PowerShell de "una cadena que contiene una barra diagonal inversa y una n" , o como una cadena literal de varias líneas. Luego ingresamos -splitesa información \s(espacios en blanco incluyendo nuevas líneas) o #filtramos todos los resultados vacíos-ne'' , por lo que nos queda solo una matriz de dígitos. Esos son alimentados en un bucle|%{...} .

Cada iteración, primero tomamos el elemento actual $_, lo convertimos en una charmatriz, -joinlo juntamos con un signo más +y lo canalizamos a iex(abreviatura deInvoke-Expression y similar a eval). Eso se almacena en, $iasí que resumimos correctamente los dígitos en este fragmento particular de la ruta. Luego usamos eso y su negativo como los dos elementos de una matriz ($i, -$i), indexados al voltear un valor booleano de un lado a otro. Es decir, la primera iteración a través de este bucle, el primer fragmento de ruta izquierda, lo indexaremos -$i; la próxima vez, tomaremos $i; y así. Esos se acumulan $acon+= .

Finalmente, evaluamos si $aes -greatert han 0. Si es así, entonces el camino derecho tenía una suma mayor, de lo contrario el camino izquierdo tenía una suma mayor. Ese resultado booleano se deja en la tubería y la salida es implícita.


2

CJam , 19 18 bytes

qN/Sf%z{'1*:~:+}/>

Pruébalo en línea!

Impresiones 0para izquierda y1 para derecha.

Explicación

q      e# Read all input.
N/     e# Split into lines.
Sf%    e# Split each line around runs of spaces.
z      e# Transpose to group each branch.
       e# Note that each branch will have the same number of digit segments
       e# now but the first branch will also have all the #s at the end in
       e# separate segments.
{      e# For each branch...
  '1*  e#   Join the segments into a single string with 1s as separators.
       e#   This will add the same number of 1s between digit segments in
       e#   both branches (which won't affect their relative sum) and it 
       e#   will also insert a 1 before each # in the first branch.
  :~   e#   Evaluate each character. The digit characters are simply turned
       e#   into their values, but # is the exponentiation operator in CJam.
       e#   This is why we inserted those additional 1s, because 1# is a no-op.
  :+   e#   Sum the digits in the branch.
}/
>      e# Check whether the left branch's sum is greater than the right one's.

1

Mathematica, 80 77 bytes

¡Gracias a Martin Ender por guardar 3 bytes!

#<#2&@@Total@Partition[Tr/@ToExpression[Characters@StringSplit@#/."#"->0],2]&

Función pura que toma una cadena delimitada por una nueva línea como entrada y vuelve Truea tomar el camino izquierdo, Falsepara tomar el camino derecho. Malditos sean esos largos nombres de comandos de Mathematica; Esto es como 10 tokens.


0

Pip , 19 18 bytes

LR+XDax:-x+$+$0SGx

Toma la entrada como una sola cadena en la línea de comando (que necesitará citar y escapar de nuevas líneas si se ejecuta en una línea de comando real). Salidas -1para izquierda, 1para derecha. Pruébalo en línea!

Explicación

Recorre ciclos de dígitos, agregando las sumas de dígitos a una cuenta. El signo de la cuenta se intercambia cada vez, con el resultado final de que los valores de la izquierda son negativos y los valores de la derecha son positivos. Luego imprimimos el signo de la cuenta final ( -1o 1).

                    a is 1st cmdline arg; XD is regex `\d`; x is "" (implicit)
                    Note that "" in a math context is treated as 0
  +XD               Apply regex + to XD (resulting in `\d+`)
LR   a              Loop over matches of that regex in a:
             $0      Regex match variable containing the full match
           $+        Sum digits by folding on +
      x:-x+          Swap the sign of the tally and add this sum
               SGx  After the loop, print the sign of the tally

0

Haskell , 64 bytes

g=sum.map fromEnum
f(a:b:r)|a>"#"=g a-g b+f r|1<3=0
(>0).f.words

Pruébalo en línea!Uso: La función anónima (>0).f.wordstoma una cadena separada de nueva línea como argumento y devuelve Falsea la izquierda y Truea la derecha.

Explicación:

Dada una entrada

 99   989
  99  89
  99 99
    #
    #
   # 

que es la cadena " 99 989\n 99 89\n 99 99\n #\n #\n #", a continuación, wordsse quitan todos los saltos de línea y espacios y devuelve una lista de las cuerdas restantes: ["99","989","99","89","99","99","#","#","#"]. La función ftoma los primeros dos elementos ay bde esta lista y comprueba si aes una cadena de dígitos comparándola con la cadena "#". (Debido a que el carbón '#'es más pequeño que todos los caracteres de dígitos '0', '1', ... cada cadena que comienza con un dígito será más grande que lexicográfico "#".) La función gmapea cada caracter en una cadena a su código de caracteres ASCII y devuelve su suma. En faplicamos ga ay by calcular para manejar las siguientes líneas. Si el camino izquierdo es más recorrido, el resultado deg a - g b , que es el valor de la ruta izquierda menos el valor de la correcta, y añadirlo a una llamada recursiva affserá negativo y de lo contrario positivo para la ruta correcta, por lo que (>0)verifica si el resultado es mayor que cero.


0

Python 3 , 84 bytes

Como todas las presentaciones actuales de Python son funciones, pensé que contribuiría con un programa completo.

x=0
try:
 while 1:
  for n in input().split():x=-x+sum(map(int,n))
except:print(x>0)

Imprime Truesi el camino izquierdo es menos transitado, de lo Falsecontrario. Pruébalo en línea!

Para cada línea de entrada, esto se divide en espacios en blanco, suma los dígitos de cada elemento resultante y lo agrega a una cuenta mientras da vuelta el signo de la cuenta en cada paso. Continúa leyendo líneas de entrada hasta que golpea una con a #, en cuyo punto se map(int,n)produce una excepción y salimos del bucle, imprimiendo Truesi la cuenta es positiva y de lo Falsecontrario.


0

Lote, 169 bytes

@echo off
set/as=0
:l
set/pr=
if not %r: =%==# call:c - %r%&goto l
cmd/cset/a"s>>9
exit/b
:c
call:r + %3
:r
set/as%1=%2%%10,d=%2/10
if %d% gtr 0 call:r %1 %d%

Imprime 0para izquierda, -1para derecha. Nota: Lee líneas hasta encontrar una con a #, luego deja de leer. La diferencia en las sumas de ruta se limita a 511 (agregue 1 byte para admitir diferencias más grandes). No más de 9 dígitos en cada fila de cada ruta (admite cualquier número de filas). Explicación: La subrutina para manejar los dígitos que se agregarán y luego cae para manejar los dos primeros parámetros. Esto significa que llamar a la subrutina con los parámetros y los dígitos izquierdo y derecho agregará los dígitos correctos y restará los dígitos izquierdos. Finalmente, el resultado se desplaza para extraer el signo.d subrutina toma dos parámetros: si sumar o restar y los dígitos. Extrae el último dígito por módulo por 10 y los dígitos restantes dividiéndolos por 10 y se llama recursivamente mientras todavía quedan dígitos. Lac subrutina toma tres parámetros: si sumar o restar, los dígitos para sumar o restar, y otros dígitos para sumar. Llama eldc-


0

Octava, 46 bytes

@(a)diff((a(:)-48)'*(bwlabel(a>35)(:)==1:2))<0

Pruébalo en línea! Una función que toma una matriz de caracteres 2D acomo entrada.

Explicación:

a=

    1   1  
     0   1 
      1   1
      1   1
      1   1
      1   1
       1 1 
        #  
        #  
        #  
         # 
          #

a > 35                   %convert the matrix to a binary matrix
                         %where there is a number corresponing
                         %element of the binary matrix is 1.

*   *  
 *   * 
  *   *
  *   *
  *   *
  *   *
   * * 

bwlabel(a>35)            %label each connected component. 


1   2  
 1   2 
  1   2
  1   2
  1   2
  1   2
   1 2 

B=bwlabel(a>35)(:)==1:2  % a binary `[n ,2]` matrix created 
                         % each column related to one of labels

A=(a(:)-48)'             % convert array of characters to array of numbers 

A * B                    % matrix multiplication that computes 
                         % the sum of numbers under each label

diff(A*B)<0              % check if the left is grater than the right

0

Java 7, 219 216 bytes

boolean c(String s){int l=0,r=0;for(String x:s.split("\n")){l+=f(x,0);r+=f(x,1);}return l>r;}int f(String x,int i){if(x.contains("#"))return 0;int n=0;for(int c:x.trim().split("\\s+")[i].getBytes())n+=c-48;return n;}

Un poco más de 52 bytes esta vez. ;)
Y nuevamente vuelve falsea la derecha ytrue por la izquierda.

Explicación:

boolean c(String s){              // Method with String parameter and boolean return-type
  int l=0, r=0;                   //  Right and left counters
  for(String x : s.split("\n")){  //  Loop over de lines
    l += f(x,0);                  //   Add all left digits to the left-counter
    r += f(x,1);                  //   Add all right digits to the right-counter
  }                               //  End of loop
  return l>r;                     //  Return whether the left-counter is larger than the right-counter
}                                 // End of method

int f(String x, int i){           // Separate method with String and integer parameters, and int return-type
  if(x.contains("#"))             //  If the current line contains "#"
    return 0;                     //   Simply return 0
  int n=0;                        //  Counter
  for(int c :                     //  Loop over the digits by
              x.trim()            //    first removing leading and trailing whitespaces
              .split("\\s+")      //    then split them right in the middle
              [i]                 //    then pick either the left or right side based on the int index parameter
              .getBytes())        //    and convert that String to a byte-array
    n += c-48;                    //   For each of those digit-characters: add it to the counter
                                  //  End of loop (implicit / single-line body)
  return n;                       //  Return the counter
}                                 // End of separate method

Código de prueba:

Pruébalo aquí.

class M{
  boolean c(String s){int l=0,r=0;for(String x:s.split("\n")){l+=f(x,0);r+=f(x,1);}return l>r;}int f(String x,int i){if(x.contains("#"))return 0;int n=0;for(int c:x.trim().split("\\s+")[i].getBytes())n+=c-48;return n;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c(" 1     2\n  1   2\n   1 2\n    #\n    #\n    #"));
    System.out.println(m.c(" 1     2\n  2   2\n   1 1\n    #\n    #\n    #"));
    System.out.println(m.c(" 12    2\n  11  2\n   1 1\n    #\n    #\n    #"));
    System.out.println(m.c(" 99   989\n  99  89\n  99 99\n  99 99\n    #\n    #\n    #\n   # "));
    System.out.println(m.c("1111 1110\n 001 111\n  11 11\n  11 11\n    #\n   ##\n  ##\n ##  "));
    System.out.println(m.c("1       1\n 0     1\n  1   1\n  1   1\n  1   1\n  1   1\n   1 1 \n    #\n    #\n    #\n     #\n      #"));
    System.out.println(m.c("1   1 \n 0   1 \n  1   1\n  1   1\n  1   1\n  1   1\n   1 1 \n    #\n    #\n    #\n     #\n      #"));
  }
}

Salida:

false
false
true
false
false
false
false
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.