Agregue peso a un lado de una sierra para equilibrarlo


13

Ley de equilibrio

Un sube y baja (supuestamente del francés 'ci-ça', que significa 'esto-eso') forma un tercio de la santísima trinidad del equipo de juegos, junto con el tobogán y el columpio igualmente ubicuos. Un sube y baja está en perfecto equilibrio si, y solo si, la suma de los momentos en cada lado es equivalente. Por lo tanto, un balancín puede equilibrarse agregando una cantidad específica de peso al lado con la suma del momento más bajo; lograr este es su objetivo para este desafío.

Desafío

Su desafío es tomar una representación de un balancín como entrada y salida nuevamente, con peso agregado a un extremo del balancín para equilibrarlo.

Entrada

Su programa debe tomar, en cualquier formato razonable, un subibaja ASCII como el siguiente:

100             100
-------------------
         ^         

La primera línea contiene dos números, cada uno representando pesos en el balancín. Exactamente un peso está presente en cada lado, cada uno actuando en el extremo de su lado de la tabla. Se garantiza que los pesos serán enteros y siempre se alinearán con su extremo correspondiente de la tabla. Estos números nunca se superpondrán con el fulcro ( ^).

La segunda línea representa el 'tablón' de la sierra. Cada guión ( -) representa una longitud igual entre sí, con la única excepción del guión directamente sobre el punto de apoyo ( ^), que no tiene longitud.

La tercera línea representa el punto de apoyo de la sierra. Este punto de apoyo está marcado por el único carácter que no es un espacio en esta línea, un circunflejo ('^'). El punto de apoyo se puede colocar en cualquier lugar a lo largo de la tabla en una entrada válida siempre que quede suficiente espacio para que los números que representan los pesos no se superpongan en la entrada o la salida.

Se garantiza que la entrada tendrá tres líneas y no tendrá espacios en blanco antes o después de los caracteres que constituyen la sierra (excepto, por supuesto, la tercera línea, que lo requiere).

Salida

Para la salida, la misma representación de balancín debe imprimirse en stdout, pero con uno (y solo uno) de los pesos reemplazados por un peso mayor, para equilibrar el balancín. Las entradas están garantizadas para hacer esto posible usando enteros solos. Por lo tanto, los pesos deben mostrarse sin puntos decimales o cualquier otra nota similar. Si su idioma no usa stdout, debe ir por consenso comunitario / meta en la salida. Las nuevas líneas finales están bien, pero cualquier otro cambio en el formato de representación probablemente no sea correcto.

Ejemplificación

Entradas de prueba y salidas correspondientes

Entrada 1

12                22
--------------------
             ^      

Salida 1

12                26
--------------------
             ^      

Entrada 2

42       42
-----------
     ^     

Salida 2

42       42
-----------
     ^     

Entrada 3

3             16
----------------
        ^      

Salida 3

14            16
----------------
        ^      

Entrada 4

1                56
-------------------
    ^              

Salida 4

196              56
-------------------
    ^              

Implementación de referencia - Python 3

# Takes a list of strings as input
def balance_seesaw(lines):
    weights = [int(w.strip()) for w in lines[0].split()]

    length  = len(lines[1])
    pivot   = lines[2].find("^")
    left_length    = pivot
    right_length   = length - 1 - pivot

    left_torque  = weights[0] * left_length
    right_torque = weights[1] * right_length

    if left_torque > right_torque:
        weights[1] = left_torque // right_length
    elif right_torque > left_torque:
        weights[0] = right_torque // left_length

    weights = [str(w) for w in weights]

    string_gap = " " * (length - sum(len(w) for w in weights))
    lines[0] = weights[0] + string_gap + weights[1]

    print("\n".join(lines))

balance_seesaw(["1                56",
                "-------------------",
                "    ^              "])

Reglas

  • Este es el , por lo que el código más corto gana contado en bytes. Verifique meta si contar bytes es incómodo en su idioma.

  • Se aplican reglas estándar / lagunas.

  • La entrada debe tomarse en un formato razonable. A continuación se ofrece una lista no exhaustiva de formatos apropiados:

    • Una sola cadena con líneas separadas por caracteres de nueva línea
    • Una lista de cadenas, cada cadena representa una línea
    • Una matriz 2D o matriz de personajes

Desafíos relacionados



¿Hay alguna razón por la que desea que la salida sea estándar? Generalmente permitimos que las funciones salgan a través de su valor de retorno.
corvus_192

@ corvus_192 Imaginé esto como un desafío de tipo 'pantalla', como un arte ASCII o 'Dibujar una bandera' o lo que sea. Una lista de cadenas como salida no es realmente 'amigable para los humanos' como tal. Si un idioma no tiene soporte stdout incorporado, se permiten otras formas de salida.
FourOhFour

Bienvenido a PPCG! Bonito primer desafío. (¡y accesorios para usar el sandbox en él también!)
AdmBorkBork

@TimmyD gracias, ha sido muy divertido ver cómo las personas abordan el problema.
FourOhFour

Respuestas:


5

05AB1E ,60 60 51 50 49 47 45 bytes

Ahorré 10 bytes gracias a Emigna y 1 byte gracias a Adnan.

Todas las líneas de entrada deben tener la misma cantidad de caracteres.

#õKD³'^¡€gDŠ*¬-Os÷1®‚*D0›*+¬?DJg²gs-ð×?¤,²,³,

#                                             Split the first input line on spaces
 õKD                                          Push [first weight, second weight] twice
    ³'^¡€gD                                   Push both lengths from either side of the pivot '^' as an array [left, right] twice
           Š*                                 Multiply by weights to get torque
             ¬-O                              Evaluate rightTorque-leftTorque
                s÷                            Divide by each side's length to get the weights to add: [deltaLeft, deltaRight], keep integer values
                  1®‚                         Push [1,-1]
                     *D                       Yield [deltaLeft, -deltaRight]
                       0›*                    Replace the negative value by 0
                          +                   Add weights: old + deltaWeight
                           ¬?                 Print left weight
                             DJg              Take the size of total decimal representation
                                ²gs-ð×?       Print a string composed of filler spaces between both new weights
                                       ¤,     Print right weight and newline
                                         ²,³, Print the last two lines from input (unchanged)

Pruébalo en línea!

Debería haber una regla general, como "si su código 05AB1E tiene más de 40 bytes, probablemente lo esté haciendo mal". Parece tan golfable, cualquier idea es bienvenida!


1
Para empezar ¬s¤s\‚puede ser õK.
Emigna

1
kD²g->(‚puede ser ¡€gsi agrega los espacios faltantes en la fila inferior del caso de prueba
Emigna

1
Gracias por la explicación. Veo que es bastante similar al algoritmo de referencia (no está mal), pero también hay algunos trucos inteligentes. Algo sobre 05AB1E significa que parece promover respuestas más inteligentes que otros lenguajes de golf; es quizás mi favorito, especialmente cuando hay una explicación incluida.
FourOhFour

1
¡Buena respuesta! Puede reemplazar 31SÍcon 1®‚:)
Adnan

1
¿Puede quizás también reemplazar / ïcon ÷.?
Emigna

5

JavaScript (ES6), 136

Probablemente no funcione en Chrome, ya que utiliza asignación desestructurada y parámetros predeterminados.

Tenga en cuenta que el método de salida JS estándar alertes particularmente inadecuado para la tarea, debido a la fuente proporcional utilizada.

(m,n,o,[p,q]=m.split(/ +/),l=n.length,h=o.indexOf`^`,g=l-h-1,c=p*h<q*g?q*g:p*h)=>alert((c/h+o).slice(0,h)+(o+c/g).slice(h-l)+`
${n}
`+o)

Menos golf

( m,n,o, // input parameters, 3 strings
  // default parameters used as local variables
  [p,q] = m.split(/ +/), // left and right weight
  l = n.length, // bar length
  h = o.indexOf`^`, // left length
  g = l-h-1, // right length
  // p*h left torque
  // q*g right torque
  c = p*h<q*g ? q*g : p*h // max torque
) => alert( (c/h+o).slice(0,h)+(o+c/g).slice(h-l) // o has enough spaces to pad left and right
     +`\n${n}\n`+o )

Prueba

F=
(m,n,o,[p,q]=m.split(/ +/),l=n.length,h=o.indexOf`^`,g=l-h-1,c=p*h<q*g?q*g:p*h)=>alert((c/h+o).slice(0,h)+(o+c/g).slice(h-l)+`
${n}
`+o)

function go()
{
  var [a,b,c]=I.value.split('\n')
  if(a.length!=b.length || a.length < c.length)
    alert('The strings are not of the same length')
  else 
  {  
    if (a.length > c.length)
      c = c+' '.repeat(a.length-c-length)
    F(a,b,c)
  }  
}
<textarea id=I>3             16
----------------
        ^      </textarea>
<button onclick='go()'>go</button>


De acuerdo con kangax.github.io/compat-table/es6 , Chrome 54 es totalmente compatible con los parámetros predeterminados y la desestructuración, por lo que no creo que tenga que preocuparse demasiado.
ETHproductions

Funciona en Chrome para mí.
DLosc

3

Perl, 149 + 2 = 151 caracteres

Requiere opciones de línea de comando -p0(esto me da una penalización de 2 bytes además de los 149 bytes en el programa mismo).

($_,$b,$c,$d)=map length,/(\d+) +(.+)
(-+)
( +)/;$r=$d/($c-$d-1);($x,$y)=$1*$r>$2?($1,$1*$r):($2/$r,$2);$_="$x$,$y",$,.=$"while$c>length;$\="
$3
$4^"

Explicación:

  • El -p0interruptor lee toda la entrada hasta el primer byte NUL o EOF. Este problema no permite NUL, por lo que obtendremos toda la entrada en la variable $_que se usa para expresiones regulares, etc., de forma predeterminada.
  • Comenzamos con una expresión regular que analiza la entrada (entre la primera y la segunda barra inclinada). Hay varias formas de analizar el primer peso (p .+?. Ej. ), Pero no puedo obtenerlo por debajo de 3 caracteres, así que también podría usar lo obvio \d+. El segundo número está al final de la línea, por lo que se puede analizar como .+(2 caracteres). La línea central se usa para determinar qué tan anchas son las escalas; se analiza como-+ (muchas otras representaciones funcionarían). Los espacios antes del cursor en la última línea son +. Una vez que aparece el símbolo de intercalación (o de hecho cualquier no espacio), ignoramos el resto de la entrada.
  • Perl captura automáticamente los cuatro grupos de la expresión regular (primer peso, el segundo peso, la fila de guiones, espacios antes del símbolo de intercalación) en $1, $2, $3, $4. Dar una expresión regular como argumento para mapusar adicionalmente una matriz de esos grupos como la matriz para mapear. Por lo tanto, tomamos sus longitudes; Esta es una manera conveniente de almacenar las longitudes $3y $4sin tener que escribir lengthdos veces. También sobrescribimos $_con la longitud de $1; Realmente no nos importa el valor de esto (el número de dígitos en la entrada izquierda es inútil), pero el hecho de que es corto ( $_la longitud es ahora el número de dígitos en el número de dígitos en el primer peso, que es necesariamente muy pequeño en comparación con el ancho de la balanza).
  • Medimos la razón $ren que se dividen las escalas.
  • $1*$r>$2comprueba para ver qué lado es más pesado. Almacenamos los nuevos pesos en $xy $y; estos tienen cálculos muy simples una vez que se conoce la relación de pesos.
  • Concatenamos $x, $,y $yen $_para producir la fila superior, luego seguimos agregando espacios ( $"contiene un solo espacio por defecto, y es más corto de lo que ' 'sería un espacio literal ) $,hasta que tenga la misma longitud que la fila central (es decir, tiene longitud $c). (Elegí la variable $,porque es una variable incorporada que se puede cambiar de forma segura en este contexto y comienza vacía por defecto). Como lengthfunciona $_de forma predeterminada, no es necesario que le demos un argumento explícito. Usé un condicional Yoda porque necesita una sintaxis considerablemente menos ambigua para analizar correctamente.
  • Finalmente, redefiní la idea de Perl de la convención de finalización de línea de salida ( $\) para contener el resto del conjunto de escalas (que es lo mismo que en la entrada, de modo que simplemente puedo usar $3y $4directamente para producir la mayor parte). Tenga en cuenta que esto significa que no hay espacios en blanco al final de la tercera línea; agregarlo haría que el programa sea un poco más largo y no parece tener ningún propósito, así que lo dejé fuera.
  • Al final del programa, el -pinterruptor se dispara nuevamente; esta vez, sale $_seguido de una "nueva línea" ( $\). Debido a que redefiní la nueva línea de salida, estas dos impresiones implícitas generan el nuevo conjunto de escalas entre ellas (aunque como efecto secundario, no hay nueva línea en la salida).
  • El -pconmutador ahora intenta leer la entrada nuevamente, pero ya sorbimos todo el archivo, por lo que lee EOF y finaliza el programa.

1

PHP, 212 209 205 bytes

probablemente golfable

preg_match("#(\d+)( +)(\d+)\s*(-+)[\r\n]+( +)\^#",$s=$argv[1],$m);echo preg_replace("#\d+( +)\d+#",(($r=$m[3])>($q=$m[1]*($p=strlen($m[5]))/(-$p-1+$e=strlen($m[4])))?$r*$e/($p+1)-$q=$r:$m[1]).$m[2].$q,$s);

Toma información del argumento de la línea de comando; escapar de las nuevas líneas. Corre con -r.


Reemplazar con un marcador de posición no funcionó como se esperaba; así que tuve que agregar más parens a la primera expresión regular.


1

Befunge 223 217 bytes

&:00p&10p~$0>~#<2#+%#1_:20p0~>8#~%#+!#1_:3v
v\g01/g03*g01_v#!\g04`*g01g04:*g03p04-1-p0<
>#g>#0>#0>#/>#<:.2\5>5>#\+/#1:#\_$50p:50g\5>5>#\+/#1:#\_$20g\-v>
1#,>#*-#4:#8_$.55+,20g>:#,1#*-#9\#5_55+,30g>:#,1#*-#8\#4_"^",@>>

Pruébalo en línea!



@ Zacharý me temo que no. Se necesita al menos una de esas flechas, de lo contrario fallará siempre que el par izquierdo> el par derecho (el primer caso de prueba, por ejemplo). El otro >creo que solo se dejó por razones estéticas. Dicho esto, parece que tengo una solución de 215 bytes en mis notas, por lo que puede ser posible (también puede tener errores que explicarían por qué nunca lo envié; no tengo tiempo para probarlo ahora).
James Holderness

1

Python 2, 184 183 bytes

Definitivamente golfable

i=raw_input
j=int
w=map(j,i().split())
W=len(i())
I=i().find('^')
R=W-I-1
a=[w[1]*R/I,w[0]*I/R]
h=a[1]>w[1]
w[h]=j(a[h])
k='\n'
print(' '*(W-len(str(w))+4)).join(map(str,w))+k+'-'*W+k+' '*I+'^'

Muy claro. Simplemente tome los pesos ajustados para ajustar ambos lados, vea cuál es más grande que el original, cambie ese y salga.

EDITAR Multiplicación y división cambiadas porque la división entera es evile (gracias a @JonathanAllan por notar esto)

EDITAR -1 byte cambiado i().index('^')a i().find('^')(gracias a @JonathanAllan [¡otra vez!])


Debe intercambiar la multiplicación y la división ya que la división es una división entera, es decir a=[w[1]*R/I,w[0]*I/R](un ejemplo simple que no funcionaría sería un 1y2 con Iy Rambos 3). Actualmente 194 no 184 por el camino desde los saltos de línea cuentan como un byte cada uno, pero jy kestán costando más bytes de lo que ahorran.
Jonathan Allan el

Puede usar I=i().find('^'), y la forma abreviada __repr__, de retroceso para hacer la última línea print`w[0]`+' '*(W-len(`w`)+4)+`w[1]`+'\n'+'-'*W+'\n'+' '*I+'^'y bajar a 182 - repl.it/EW8f
Jonathan Allan

0

C ++ 14, 482 bytes

include<iostream>#include<string>#include<math.h>usingnamespacestd;intmain(){stringa,b,c,d;intj=0;inte[2];getline(cin,a);getline(cin,b);getline(cin,c);for(inti=0;i<a.size();i){if(isdigit(a.at(i))){while(i<a.size()&&isdigit(a.at(i))){d=a.at(i);i;}e[j]=stoi(d);d="";}}strings(b.size()-(int)log10(e[0])-(int)log10(e[1])-2,'');intl1=(c.size()-1);intl2=(b.size()-c.size());intl=e[0]*l1;intr=e[1]*l2;if(l>r)e[1]=l/l2;elsee[0]=r/l1;cout<<e[0]<<s<<e[1]<<endl;cout<<b<<endl;cout<<c;return0;}

versión más legible:

#include <iostream>
#include <string>
#include <math.h>
using namespace std;
int main() {
    string a,b,c,d;
    int j=0;
    int e[2];
    // input
    getline(cin,a);// 1st line
    getline(cin,b);// 2nd line
    getline(cin,c);// 3rd line
    for (int i=0;i<a.size();i++) {
        if(isdigit(a.at(i))){
            while(i<a.size() && isdigit(a.at(i))){
                d+=a.at(i);
                i++;
            }
            e[j++]=stoi(d);
            d="";
        }
    }
    // amount of white space in between 2 numbers
    string s(b.size()-(int)log10(e[0])-(int)log10(e[1])-2,' ');
    int l1 = (c.size()-1);
    int l2 = (b.size()-c.size());
    int l = e[0]*l1;
    int r = e[1]*l2;
    // change the side with smaller torque
    if (l>r)
        e[1]=l/l2;
    else
        e[0]=r/l1;
    // output
    cout<<e[0]<<s<<e[1]<<endl;// 1st line
    cout<<b<<endl;// 2nd line
    cout<<c;// 3rd line
    return 0;
}

0

Python 3, 235 230 bytes (referencia minimizada)

Simplemente minimicé la referencia, ya que soy muy nuevo en el golf de código.

def s(l):
 w,i,t=[int(z.strip())for z in l[0].split()],len(l[1]),l[2].find("^");k,o=i-1-t,w[0]*t;p=w[1]*k
 if o>p:w[1]=o//k
 else:w[0]=p//t
 w=[str(z)for z in w];s=" "*(i-sum(len(z)for z in w));l[0]=w[0]+s+w[1];print("\n".join(l))

Lo usa exactamente igual que en el ejemplo, pero la función es en slugar de balance_seesaw.


Las líneas 5 y 6 podrían convertirse w[o>p]=[o//k,p//t][o>p]. Además, la mayoría de las líneas podrían unirse para eliminar algunos espacios en blanco adicionales.
James

Gracias, como dije, soy muy nuevo, así que paso por alto incluso las soluciones más simples.
ender_scythe

Excepto que no funciona, sino que proporciona 0,56 en lugar de 196,56.
ender_scythe
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.