¿Me volcaré?

36

Visión general

Dada una cadena de 3 líneas, averigua si la estructura cae a la izquierda, se equilibra o cae a la derecha.

Estructura de entrada

Puedes imaginar la estructura como una barra de metal con cosas en la parte superior, todo equilibrado en la parte superior de una barra vertical.

1  7 4        a
===============
        |

La primera línea son los artículos. El peso de cada elemento se calcula como el valor ascii del personaje menos 32. (Los caracteres menores de 32 no se consideran y los espacios pesan 0). Tenga en cuenta que la fuerza de un artículo sobre la barra es su peso multiplicado por la distancia al punto de pivote.

La segunda línea es la barra. Cada longitud de barra pesa 1 unidad por sí misma. Esta línea es exclusivamente igual a signos ( =).

La tercera línea es el punto de pivote. Esto se puede colocar en cualquier lugar, y está representado por una cantidad de espacios seguidos de un solo carácter de barra vertical ( |).

Ejemplos

Entrada:

=====
  El |

Salida: Balance

Entrada:

=====
   El |

Salida: cae a la izquierda

Entrada:

    %
=====
   El |

Salida: Balance (porque %pesa lo suficiente como para contrarrestar el peso del lado izquierdo de la barra)

Entrada:

 Automóvil club británico
=======
   El |

Salida: cae a la derecha (porque la aderecha está más lejos del punto de pivote)

Entrada:

1  7 4        A
===============
        |

Salida: cae a la izquierda

Entrada:

1  7 4        a
===============
        |

Salida: cae a la derecha (las letras minúsculas son pesadas)

Entrada:

            $ ~
===============
             |

Salida: Balance

Notas

  • El espacio en blanco final está permitido, el espacio en blanco inicial no.
  • Su programa puede emitir en el formato que desee, siempre que haya 3 salidas distintas para izquierda, balance y derecha.
  • Su programa debe aceptar el formato que se muestra como entrada.
Daffy
fuente
1
Muy relacionado
Luis Mendo
¿Puede el programa tomar las tres líneas como tres cadenas separadas (por ejemplo, como tres argumentos para una función o como una lista de tres elementos)?
notjagan
@notjagan La entrada debe ser una sola cadena separada por nuevos caracteres de línea.
Daffy
Relacionados , posible engaño.
xnor
@xnor No es un tonto porque esa pregunta trata solo con letras mayúsculas, y su objetivo es encontrar el pivote. Mi pregunta es sobre todos los caracteres ascii> = 32, y el mío proporciona el pivote y pregunta si la estructura se caerá. Esencialmente el reverso del que vinculaste.
Daffy

Respuestas:

8

JavaScript (ES6), 116 111 108 106 bytes

-5 bytes sumando via en eval(array.join`+`)lugar de array.reduce().
-3 bytes por defecto en 1lugar de 32 - 31, permitiendo que se eliminen los paréntesis.
-2 bytes ya que el punto de pivote es la longitud de la última línea - 1

(s,[t,r,b]=s.split`
`)=>Math.sign(eval([...r].map((_,i)=>(t.charCodeAt(i)-31||1)*(i-b.length+1)).join`+`))

Salidas -1, 0o 1, para izquierda, balanceada o derecha, respectivamente. Terminó de manera similar a la respuesta de Python de Chas Brown , por lo que el crédito va allí.

Puede guardar 4 bytes si la primera línea se rellena para que coincida con la longitud de la barra usando
(31-t.charCodeAt(i))*(b.length+~i).

Fragmento de prueba

Incluye salida adicional ( Left/ Balanced/ Right) junto con el número.

f=
(s,[t,r,b]=s.split`
`)=>Math.sign(eval([...r].map((_,i)=>(t.charCodeAt(i)-31||1)*(i-b.length+1)).join`+`))
<textarea id=I rows=3 cols=20></textarea><br><button onclick="O.value=I.value?`${x=f(I.value)} (${['Left','Balanced','Right'][x+1]})`:''">Run</button> <input id=O disabled>

Otro método de 106 bytes

(s,[t,r,b]=s.split`
`)=>Math.sign(eval(r.replace(/./g,(_,i)=>"+"+(t.charCodeAt(i)-31||1)*(i-b.length+1))))

En lugar de crear una joinmatriz en +s, creamos una cadena de números, cada uno con el prefijo +. El líder +se ignora.

Justin Mariner
fuente
1
Creo que (b.length+~i)podría ayudar a salvar un byte. (Además, no entiendo por qué tienes el ||1.)
Neil
1
@Neil b.length+~idevuelve el negativo de i-b.length+1; eso podría ayudar si pudiera negar la otra parte. En cuanto a ||1eso, fue porque estaba asumiendo que la primera línea no estaba acolchada para que coincidiera con la longitud de la barra, por t.charCodeAt(i)lo que volvería NaNmás allá del final de la primera línea.
Justin Mariner el
Sin embargo, no había probado un caso de prueba sin relleno; gracias por la explicación.
Neil
3

Python 2 , 112 110 bytes

def f(s):w,b,p=s.split('\n');return cmp(sum((ord((w+' '*-~i)[i])-31)*(i-p.find('|'))for i in range(len(b))),0)

Pruébalo en línea!

EDITAR: Finalmente logró eliminar el enumeratey rjustpor unos miserables 2 bytes ... ¡meh!

Toma una cuerda; salidas -1,0, o 1 para caídas a la izquierda, saldos, caídas a la derecha, respectivamente.

El primer paso a 112 bytes fue:

def f(s):w,b,p=s.split('\n');return cmp(sum((ord(c)-31)*(i-p.find('|'))for i,c in enumerate(w.rjust(len(b))),0)
Chas Brown
fuente
(ord(c)-31)Me tomó un tiempo darme cuenta de que esto realmente está incorporando el peso de la barra junto con los artículos. ¡Muy inteligente!
Daffy
1
Según meta , se puede sustituir returncon printde -1 bytes (aunque en realidad no jugar bien con el código TIO actual).
notjagan
3

Haskell, 212 171 bytes (188 si toma la entrada como una cadena)

o!p=map(fst)(zip[p-0,p-1..]o)
x#p=sum(zipWith(\c w->(max(fromEnum c-32)0)*w)x(x!p))+sum(x!p)
x?c=length(takeWhile(==c)x)

Variante de 171 bytes

r a b c=signum(take(b?'=')(a++repeat ' ')#(c?' '))

Variante 188 bytes

x%y=lines x!!y
r i=signum(take(i%1?'=')(i%0++repeat ' ')#(i%2?' '))

Explicación

o!p=map(fst)(zip[p-0,p-1..]o)        Creates weights coefs list. 
                                     o - list, p - pivot position
                                     for list "abcdf" and p=3 (pivot under 'd')
                                     outputs [3,2,1,0,-1]

x#p                                  Calculates total balance
                                     x-list of "objects" on lever, p-pivot place
  sum(zipWith                        sum of zipped lists
   (\c w->(max(fromEnum c-32)0)*w)   weight of ascii "object" times
                                     distance from pivot
    x(x!p))                          x-ascii objects, 
                                     (x!p)-distances list(weight coefs)
  +sum(x!p)                          balance of lever ("==") itself

x?c=length(takeWhile(==c)x)          length of list before non c element met
                                     used to find '|' position
                                     and length of "===" lever
                                     before right whitespaces met

r a b c=                             Sums it all up =)
                                     a-ascii objects, b-lever, c-pivot line
   signum(                           1-tips left, 0-balance, -1-tips right
     take(b?'=')(a++repeat ' ')      takes all object on lever 
                                     plus whitespaces up to length of the lever
      #                              calculate the balance
       (c?' ')                       determine place of pivot
Sergii Martynenko Jr
fuente
1
Puede usar en fromEnumlugar de ordy soltar el import. cpuede simplificarse a c p=max(ord p-32)0(o con fromEnum) y, como lo está utilizando solo una vez, inlineelo.
nimi
O puede agregar (Lambdabot) a su título, esto importa casi todo lo que necesita, vea aquí .
ბიმო
1
La función cincluso se puede simplificar (no se consideran los caracteres menores de 32) c p=ord p-32. También pes básicamente length(menos 1), por p x=length x-1lo que también funcionaría (y también puede incluirlo en línea). También eche un vistazo a mi solución, cómo uso signum: podría hacer lo r o l s = signum $ 2 * z ...que devuelve 0,1,-1B, L, R.
ბიმო
1
Además, esta solución parece fallar en los casos de prueba [3,4,7]y toma 3 cadenas en lugar de una. (ver lines)
ბიმო
1
Aquí hay una versión con algunos consejos aplicados (le ahorra 29 bytes;)).
ბიმო
2

Jalea , 30 bytes

O_31×J_¥A+\sṪ€µ÷ḢṪ_2Ṡ
ỴṪLç@ỴḢ$

Banco de pruebas

Salidas 0 para balanceado, 1 para derecha y -1 para izquierda.

Cómo funciona

O_31×J_¥A+\sṪ€µ÷ḢṪ_2Ṡ - helper function. Arguments position of pivot and first line
O                        - char codes of first line
 _31                     - subtract 31 to get weight
    ×                    - elementwise product with:
     J_¥                 - distances from the pivot
        A                - absolute value
         +\              - cumulative sum
           s             - split to get [[...,left weight],...,[..., right + left weight]]
            Ṫ€           - last element of each sublist: [left weight, ... right weight]
              µ÷Ḣ        - get ratio of each element over left weight: ratio n indicates
                              right + left = n × left ===> right = left if n = 2
                 _2      - subtract 2: positive is right>left and negative is right<left
                   Ṡ     - return the sign of this


ỴṪLç@ỴḢ$              - main link. Argument: 3 line string.
   ç@                  - apply helper function with arguments:
Ỵ                        - split by linefeeds
 Ṫ                       - last line
  L                      - length (returns position of pivot)
       $               - and
     Ỵ                   - split by linefeeds
      Ḣ                  - first line              
fireflame241
fuente
2

Jalea , 24 bytes

ṪO_31
ỴµṪLạЀṪL$×Çṣ0S€IṠ

Pruébalo en línea!

-1para caer a la izquierda, 0para equilibrar, 1para caer a la derecha (programa completo).
[-1]para caer a la izquierda, [0]para equilibrar, [1]para caer a la derecha (función).

La primera línea debe tener espacios finales, la última línea no debe.

Explicación (comenzamos con el resultado final):

En primer lugar, estamos trabajando con líneas individuales, por lo que debemos obtenerlas de alguna manera. Ese es un trabajo para . Luego, debemos tratar la \nversión -split de la entrada como si fuera la entrada original, así que usamosµ para hacer una cadena monádica aplicada al valor actual.

Ahora comenzamos un trabajo real, y nuestro primer trabajo sería calcular los factores de los pesos. Esencialmente, este es un rango [distancia desde el extremo izquierdo al pivote ... 0..distancia desde el pivote hasta el extremo derecho]. En primer lugar, tenemos que encontrar el índice basado en 1 del pivote, que es esencialmente la longitud de la última línea sin espacios finales. Entonces, sacamos la última línea (línea dinámica) de nuestra lista original , ya que no la necesitaremos más, y luego tomamos su longitud con L. Luego necesitamos tomar la longitud de la barra, para lo cual hacemos lo mismo con la última línea (línea de barra) ṪL$. Finalmente, para obtener el rango, mapeamos | x - y | a [1..longitud del cable], donde x es el índice de pivote e yes cada elemento de la lista que asignamos. Hacemos esto usando ạЀ, donde calcula | x - y | y Ѐhace un rango de 1 hasta e incluyendo la longitud de la barra. Ahora tendremos el rango que queremos.

Después de eso, tenemos que multiplicar cada número entero, representando una pieza de la barra, con su peso correspondiente. Para calcular los pesos, usamos Ç, yendo a la línea superior de nuestro código. Tomamos la línea restante con sus códigos de char con O, y luego calculamos x - 31 usando _31, siendo x cada código de char. Luego asignamos espacio al peso 1 (0 + pieza de barra = 1), !al peso 2 (1 + 1), etc. Hemos terminado con la línea superior, por lo que ahora Çdevolveríamos la lista de pesos, que multiplicamos con el correspondiente enteros que representan las piezas de la barra con ×.

Después de eso, nos dividimos ṣ0en el punto de pivote, representado por un 0 (ya que cualquier peso no afectará el resultado), lo que da como resultado una lista de la forma [[1er peso, 2do peso ... peso justo antes del pivote] , [peso justo después del pivote, peso después del anterior ... último peso]]. Esas listas representan los lados de la barra, izquierda y derecha. Ahora sumamos cada una de las listas usando S€para obtener los pesos totales en cada lado, y usamos Ipara tomar el delta, que será negativo si el lado izquierdo es más pesado, cero si tienen el mismo peso y positivo si el lado derecho es más pesado . Por lo tanto, para devolver el resultado final utilizando esto adecuadamente para nuestro beneficio, tomamos la señal con .

Erik el Outgolfer
fuente
2

APL (Dyalog) , 43 bytes *

{×(¯31+⎕UCS⊃⍵)+.×(⍳≢⊃⍵)-'|'⍳⍨⊃⌽⍵}⎕TC[2]∘≠⊆⊢

Pruébalo en línea!

⊆⊢ dividir el argumento en series de caracteres que son

⎕TC[2]∘≠ diferente de la 2 nd T ERMINAL C ontrol carácter (avance de línea) **

{... } aplique la siguiente función anónima en la lista de cadenas:

⊃⌽⍵ en la primera cadena de la lista invertida (es decir, la última)

'|'⍳⍨ encontrar el índice of del punto de pivote

()- Reste eso de la siguiente lista:

  ⊃⍵ la primera cuerda

   su longitud

   todos los ɩ nices de eso

(...)+.×  Suma ponderada con esos pesos y los siguientes valores:

  ⊃⍵ la primera cuerda

  ⎕UCS puntos de código en la U NIVERSAL C r incón dele S et

  ¯31+ agregue treinta y uno negativo (32 para el desplazamiento requerido menos uno para la barra)

× signo de eso


* Para 1 byte por char, use {×(¯31+⎕UCS↑⍵)+.×(⍳≢↑⍵)-'|'⍳⍨↑⌽⍵}⎕TC[3]∘≠⊂⊢con ⎕ML←3. Pruébalo en línea!
** ⎕TCestá en desuso y se usa aquí solo para fines de golf. En el código de producción, uno debe usar ⎕UCS 10.

Adán
fuente
2

Haskell (Lambdabot), 142 bytes

l=length
g[a,c,b]=splitAt(l b)$a++(' '<$[1..l c-l a])
k e=sum$zipWith((*).(-31+).ord)e[1..]
f=signum.uncurry(-).(k.drop 1.reverse***k).g.lines

Pruébalo en línea!

Versión sin golf:

-- for readability, allows reading top-down/left-right
(.>) = flip (.)

ungolfed =
     lines                                 -- separate out lines into..
  .> (\[a,b,c] ->                          -- a,b,c (first,second,third)
                                           -- ' ' pad the first line & split on pivot
       splitAt (length c) (a ++ replicate (length b - length a) ' ')
     )
  .> (weight.drop 1.reverse *** weight)    -- reverse left half, drop element above pivot & get weight for both
  .> uncurry (-)                           -- subtract right from left
  .> signum                                -- get sign

-- get ord of the character subtract 31 ('=' char from bar),
-- then multiply with scales ([1..]) and sum it all up
weight es = sum $ zipWith (ord .> subtract 31 .> (*)) es [1..]
ბიმო
fuente
2

Python 2 , 90 bytes

def f(s):L=len(s)/3;print cmp(sum((ord(s[i])-31)*(i-s[-L:].find('|'))for i in range(L)),0)

Espera que las líneas de entrada se rellenen (con espacios) a la longitud correcta. Salidas -1para caídas a la izquierda , 0para equilibradas y 1para caídas a la derecha .

Pruébalo en línea!


94 bytes

Para +4 bytes podemos tener una versión que, usando un whilebucle, requiere líneas despojadas en lugar de líneas rellenas :

def f(s):
 i=r=0
 while''<s[i]:r+=(ord(s[i])-31)*(i-s[-3::-1].find('='));i+=1
 print cmp(r,0)

Pruébalo en línea!

FlipTack
fuente
1

Rubí, 543 bytes

def willittip(s)
leftw=0;
rightw=0;
arr=[];
fields=s.split("\n")
pos=fields[2].index("|")
fields[0].split("").each do |i|
arr << i.ord-32
end
arr[pos+1..-1].each_with_index do |x,y|
rightw=rightw+1
if x>0
if pos>0
rightw=rightw+x*(pos-y).abs
else
rightw=rightw+x
end
end
end
arr[0..pos-1].each_with_index do |x,y|
leftw=leftw+1
if x>0
if pos>0
leftw=leftw+x*(pos-y).abs
else
leftw=leftw+x
end
end
end
if leftw==rightw
return "Equal"
elsif leftw<rightw
return "Right"
elsif leftw>rightw
return "Left"
end
end
KittenDev
fuente
10
Bienvenido a PPCG! : D El objetivo de los desafíos de código de golf es hacer que su código sea lo más pequeño posible. Puede reducir el tamaño de su código haciendo que todas las variables y nombres de funciones sean un solo carácter, y eliminando espacios en blanco siempre que sea posible.
Daffy
1

C (gcc) , 106107 121 123 124 129 129 131 bytes

c,b,l,i;f(char*a){l=strlen(a)/3;for(i=b=c=0;32/a[l*2+c];++c);for(;i<l-1;b+=(a[i]-31)*(i++-c));a=b>0?2:!b;}

Regrese 0 para caer a la izquierda, 1 para mantener el equilibrio y 2 para caer a la derecha.

Exija que las tres líneas tengan la misma longitud y termine \npara determinar la longitud de la cuerda.

Pruébalo en línea!

Keyu Gan
fuente
1

Mathematica, 91 92 bytes

Sign[(v=(g=ToCharacterCode)@#&@@(d=#~StringSplit~"
")-31).(Range@(l=Length)@v-l@g@Last@d)]&

La primera línea debe tener la misma longitud con la varilla. La tercera línea no debe contener espacios finales.

Regrese -1, 0, 1 por caer a la izquierda, equilibrar y caer a la derecha.

Keyu Gan
fuente
1

C # (.NET Core) , 127 95 90 + 18 = 108 bytes

Para esta función, la primera línea debe estar rellenada a la derecha con espacios que tengan la misma longitud que la barra y la tercera línea no debe tener espacios de prueba. Estas condiciones están permitidas (ver comentarios de la pregunta).

s=>s.Split('\n')[0].Select((c,i)=>(c-31)*(i-s.Split('\n')[2].Length+1)).Sum().CompareTo(0)

Pruébalo en línea!

Salidas:

-1 para punta izquierda
0 para balance
1 para punta derecha

raznagul
fuente
1

Python 3, 217 bytes

También funciona en Python 2.7

def f(s):i,b,p=s.split('\n');c=p.find('|');l=sum((ord(e)-32)*(c-i.find(e))for e in i[:c])+sum(x for x in range(1,c+1));r=sum((ord(e)-32)*i[c:].find(e)for e in i[c:])+sum(x for x in range(len(b[c:])));return(l>r)-(r>l)

Devuelve 1 para el lado izquierdo, -1 para el lado derecho o cero si está equilibrado.

Versión legible:

def f(s):
    i,b,p = s.split('\n')
    c = p.find('|')

    l = sum((ord(e)-32)*(c-i.find(e))for e in i[:c])+sum(x for x in range(1, c+1))
    r = sum((ord(e)-32)*i[c:].find(e)for e in i[c:])+sum(x for x in range(len(b[c:])))

    return(l>r)-(r>l)
veganaiZe
fuente
1
No es necesario sum([...]), simplemente puede tenersum(...)
Sr. Xcoder
@Daffy, esto debería ser 100% conforme a su especificación y todas las entradas de ejemplo dadas. Si está de acuerdo, hágamelo saber para que pueda optimizarlo aún más. Gracias.
veganaiZe
@veganaiZe Pasó todas mis pruebas, ¡se ve bien! :)
Daffy
1
Cosas para acortarlo: i[c:].find(e)puede ser i.find(e,c), usar i,m,n=s.split('\n')y evitar la necesidad s, usar return 2*(r>l) or l>rpara reducir drásticamente el costo de la prueba al final (el valor de retorno es numéricamente equivalente, pero es en Truelugar de 1y en Falselugar de 0), o realmente, usar un conjunto diferente de retorno valores y hacer return (l>r)-(r>l)para devolver el 1, 0 o -1 como lo cmphizo la función anterior.
ShadowRanger
¡Gracias ShadowRanger, Mr. Xcoder y Daffy! @ShadowRanger Tuve que seguir con el i[c:]porque la forma más corta causó un problema extraño de uno por uno para alguna entrada de mayúsculas y minúsculas (intente colocar |exactamente en el medio, encima de la barra).
veganaiZe
1

PHP, 105 bytes

for([$a,$b,$c]=explode("
",$argn);$b[$i];)$w+=(strpos($c,"|")-$i++)*8*(max(1,ord($a[$i])-31));echo$w<=>0;

impresiones -1/ 0/ 1a la izquierda / equilibrio / derecha. Ejecutar como tubería -nRo probarlo en línea .

Descompostura

for([$a,$b,$c]=explode("\n",$argn); # import input
    $b[$i];)                        # loop through bar
    $f+=                                # add to force:
        ($i-strpos($c,"|"))             # distance (<0 if left, >0 if right of pivot)
        *8                              # *8
        *(max(1,ord($a[$i++])-31));     # *weight
echo$f<=>0;                         # print -1 if $f<0, 1 if $f>0, 0 if $f==0
Titus
fuente
1

Carbón , 31 bytes

A⁰ξFLθA⁺ξ×⁻ι⌕ζ|⁻℅§θι³¹ξI⁻›ξ⁰‹ξ⁰

Pruébalo en línea! El enlace es a la versión detallada del código. Salidas 0 para balance o -1 o 1 para caer hacia la izquierda o hacia la derecha. Editar: Los cambios en el carbón ahora significan que ≔ΣEθ×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰funciona para 24 bytes: ¡ Pruébelo en línea! El enlace es a la versión detallada del código. Nota: Ambas respuestas requieren una entrada rellenada, pero se pueden adaptar para aceptar entradas sin relleno a un costo de 3 bytes: ¡ ≔⁰ξFLη≔⁺ξ×⁻ι⌕ζ|⁻℅§◨θLηι³¹ξI⁻›ξ⁰‹ξ⁰ Pruébelo en línea! ≔ΣE◨θLη×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰ Pruébalo en línea!Los enlaces son a la versión detallada del código.

Neil
fuente
Es posible que desee mencionar esto, esto espera que las líneas de entrada se rellenen a la longitud correcta con espacios, por lo que una entrada sin relleno puede no funcionar.
FlipTack
@FlipTack Mejor aún, he ideado versiones que aceptan entradas sin relleno.
Neil