Aggiungi peso su un lato di una sega per bilanciarlo


13

Atto di bilanciamento

Una sega (presumibilmente dal francese "ci-ça", che significa "questo-quello") forma un terzo della sacra trinità dell'attrezzatura da gioco, insieme allo scivolo e all'oscillazione altrettanto onnipresenti. Un see-saw è in perfetto equilibrio se, e solo se, la somma dei momenti su ciascun lato è equivalente. Una sega può quindi essere bilanciata aggiungendo una quantità specifica di peso al lato con la somma del momento inferiore; raggiungere questo è il tuo obiettivo per questa sfida.

Sfida

La tua sfida è quella di prendere una rappresentazione di una sega come input e di produrla di nuovo, con il peso aggiunto a un'estremità della sega per bilanciarla.

Ingresso

Il tuo programma deve assumere, in qualsiasi formato ragionevole, un see-saw ASCII come il seguente:

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

La prima riga contiene due numeri, ognuno dei quali rappresenta i pesi sulla troncatrice. Esattamente un peso è presente su ciascun lato, ciascuno agendo all'estremità del suo lato della tavola. I pesi sono garantiti come numeri interi e si allineano sempre con l'estremità corrispondente della tavola. Questi numeri non si sovrapporranno mai al fulcro ( ^).

La seconda riga rappresenta la "tavola" della troncatrice. Ogni trattino ( -) rappresenta una lunghezza uguale tra loro, con la sola eccezione del trattino direttamente sopra il fulcro ( ^), che non ha lunghezza.

La terza linea rappresenta il fulcro della troncatrice. Questo fulcro è contrassegnato dall'unico carattere che non è uno spazio su questa linea, un circonflesso ('^'). Il fulcro può essere posizionato ovunque lungo la lunghezza della tavola in un input valido purché rimanga spazio sufficiente in modo che i numeri che rappresentano i pesi non si sovrappongano nel fulcro nell'input o nell'output.

È garantito che l'input abbia tre righe e che non vi siano spazi bianchi prima o dopo i caratteri che costituiscono il see-saw (tranne, ovviamente, la terza riga, che lo richiede).

Produzione

Per l'output, la stessa rappresentazione della sega dovrebbe essere stampata su stdout, ma con uno (e solo uno) dei pesi sostituito con un peso maggiore, in modo da bilanciare la sega. Gli input sono garantiti per renderlo possibile utilizzando solo numeri interi. Pertanto, i pesi devono essere visualizzati senza punti decimali o altre notazioni simili. Se la tua lingua non usa stdout, dovresti andare per comunità / meta consenso sull'output. Le nuove righe finali vanno bene, ma qualsiasi altra modifica al formato di rappresentazione probabilmente non è corretta.

Esemplificazione

Ingressi di prova e uscite corrispondenti

Ingresso 1

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

Uscita 1

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

Ingresso 2

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

Uscita 2

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

Ingresso 3

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

Uscita 3

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

Ingresso 4

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

Uscita 4

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

Implementazione di riferimento - 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",
                "-------------------",
                "    ^              "])

Regole

  • Questo è , quindi il codice più corto vince contato in byte. Controlla meta se il conteggio dei byte è scomodo nella tua lingua.

  • Si applicano le regole / scappatoie standard.

  • L'input deve essere preso in un formato ragionevole. Un elenco non esaustivo di formati appropriati è fornito come segue:

    • Una singola stringa con linee separate da caratteri di nuova riga
    • Un elenco di stringhe, ciascuna stringa rappresentava una riga
    • Una matrice 2D o una matrice di caratteri

Sfide correlate



C'è qualche motivo per cui vuoi che l'output sia stdout? Generalmente consentiamo alle funzioni di essere emesse tramite il loro valore di ritorno.
corvus_192,

@ corvus_192 L'ho immaginato come una sfida di tipo "display", come un'arte ASCII o "Disegna una bandiera" o altro. Un elenco di stringhe come output non è realmente "umano-friendly" in quanto tale. Se una lingua non ha il supporto stdout integrato, sono comunque consentiti altri moduli di output.
FourOhFour

Benvenuti in PPCG! Bella prima sfida. (e oggetti di scena per usare anche la sandbox!)
AdmBorkBork,

@TimmyD grazie, è stato molto divertente vedere come le persone affrontano il problema.
FourOhFour

Risposte:


5

05AB1E ,60 51 50 49 47 45 byte

Risparmiato 10 byte grazie a Emigna e 1 byte grazie ad Adnan.

Tutte le righe di input devono avere la stessa quantità di caratteri.

#õ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)

Provalo online!

Dovrebbe esserci una regola empirica, come "se il tuo codice 05AB1E è più lungo di 40 byte, probabilmente stai sbagliando". Sembra così giocabile a golf, ogni idea è benvenuta!


1
Per cominciare ¬s¤s\‚può essere õK.
Emigna,

1
kD²g->(‚può essere ¡€gse aggiungi gli spazi mancanti nella riga inferiore del test case
Emigna

1
Grazie per la spiegazione. Vedo che è abbastanza simile all'algoritmo di riferimento (niente male) ma ci sono anche alcuni trucchi intelligenti. Qualcosa su 05AB1E significa che sembra promuovere risposte più intelligenti di altri linguaggi del golf - è forse il mio preferito soprattutto quando c'è una spiegazione inclusa.
FourOhFour

1
Bella risposta! Puoi sostituirlo 31SÍcon 1®‚:)
Adnan,

1
Puoi forse sostituire anche / ïcon ÷.
Emigna,

5

JavaScript (ES6), 136

Probabilmente non funziona in Chrome, in quanto utilizza assegnazioni destrutturate e parametri predefiniti.

Si noti che il metodo di output JS standard non alertè particolarmente adatto per l'attività, a causa del carattere proporzionale utilizzato.

(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)

Meno 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 )

Test

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>


Secondo kangax.github.io/compat-table/es6 , Chrome 54 supporta pienamente i parametri predefiniti e la destrutturazione, quindi non penso che ti debba preoccupare troppo.
ETHproductions

Funziona su Chrome per me.
DLosc,

3

Perl, 149 + 2 = 151 caratteri

Richiede le opzioni della riga di comando -p0(questo mi dà una penalità di 2 byte sopra i 149 byte nel programma stesso).

($_,$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^"

Spiegazione:

  • Lo -p0switch legge l'intero input fino al primo byte NUL o EOF. Questo problema non consente NUL, quindi otterremo l'intero input nella variabile $_utilizzata per regex, ecc., Per impostazione predefinita.
  • Iniziamo con una regex che analizza l'input (tra la prima e la seconda barra). Esistono diversi modi in cui è possibile analizzare il primo peso (ad es. .+?), Ma non riesco a farlo sotto i 3 caratteri, quindi posso anche usare l'ovvio \d+. Il secondo numero si trova alla fine della riga, quindi può essere analizzato come .+(2 caratteri). La linea centrale viene utilizzata per determinare la larghezza delle scale; viene analizzato come -+(molte altre rappresentazioni funzionerebbero). Gli spazi prima del cursore sull'ultima riga sono +. Una volta che appare il punto di inserimento (o effettivamente qualsiasi non spazio), ignoriamo il resto dell'input.
  • Perl acquisisce automaticamente i quattro gruppi di regex (primo peso, secondo peso, fila di trattini, spazi prima del cursore) in $1, $2, $3, $4. Dare una regex come argomento per maputilizzare inoltre una matrice di quei gruppi come matrice su cui mappare. Quindi prendiamo le loro lunghezze; questo è un modo conveniente per memorizzare le lunghezze di $3e $4senza dover scrivere lengthdue volte. Sovrascriviamo anche $_con la lunghezza di $1; non ci interessa davvero il valore di questo (il numero di cifre nell'input sinistro è un po 'inutile), ma il fatto che sia breve ( $_la lunghezza è ora il numero di cifre nel numero di cifre nel primo peso, che è necessariamente molto piccolo rispetto alla larghezza delle scale).
  • Misuriamo il rapporto $rin cui le scale sono divise.
  • $1*$r>$2controlla per vedere quale lato è più pesante. Conserviamo i nuovi pesi in $xe $y; questi hanno calcoli molto semplici una volta noto il rapporto dei pesi.
  • Concateniamo $x ,$, e $yin $_per produrre la riga superiore, quindi continuiamo ad aggiungere spazi ( $"contiene un singolo spazio per impostazione predefinita, ed è più corto di uno spazio letterale ' ') su $,fino a quando non ha la stessa lunghezza della riga centrale (cioè ha lunghezza $c). (Ho scelto la variabile in $,quanto è una variabile incorporata che può essere tranquillamente modificata in questo contesto e inizia vuota per impostazione predefinita.) Dato che lengthopera $_di default, non è necessario fornirle un argomento esplicitamente. Ho usato un condizionale Yoda perché ha bisogno di una sintassi notevolmente meno chiara per analizzare correttamente.
  • Infine, ridefinisco l'idea di Perl della convenzione di fine linea di output ( $\) per contenere il resto dell'insieme di scale (che è lo stesso dell'input, quindi posso semplicemente usare $3e $4direttamente per produrre la maggior parte di esso). Si noti che ciò significa che non vi è spazio bianco finale sulla terza riga; aggiungerlo renderebbe il programma leggermente più lungo e non sembrerebbe servire a nessuno scopo, quindi l'ho lasciato fuori.
  • Alla fine del programma, l' -pinterruttore si innesca di nuovo; questa volta, viene emesso $_seguito da un "newline" ( $\). Poiché ho ridefinito la nuova riga di output, queste due stampe implicite generano il nuovo set di scale tra di loro (anche se come effetto collaterale, non ci sono newline sull'output).
  • Il -p switch ora prova a leggere di nuovo l'input, ma abbiamo già sequestrato l'intero file, quindi legge EOF e termina il programma.

1

PHP, 212 209 205 byte

probabilmente 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);

Accetta input dall'argomento della riga di comando; sfuggire alle nuove linee. Corri con -r.


La sostituzione con un segnaposto non ha funzionato come previsto; così ho dovuto aggiungere più parentesi al primo regex.


1

Befunge, 223 217 byte

&: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_"^",@>>

Provalo online!



@ Zacharý Temo di no. È necessaria almeno una di quelle frecce, altrimenti fallirà ogni volta che si verifica una coppia sinistra> coppia destra (ad esempio il primo caso di test). L'altro >penso sia stato lasciato solo per motivi estetici. Detto questo, mi sembra di avere una soluzione di 215 byte nelle mie note, quindi potrebbe essere possibile (anche il mio ha dei bug che spiegherebbero perché non l'ho mai inviato - non ho tempo di provarlo ora).
James Holderness,

1

Python 2, 184 183 byte

Decisamente golfabile

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+'^'

Abbastanza diretto. Basta prendere i pesi regolati per regolare entrambi i lati, vedere quale è più grande dell'originale e cambiare quello e l'output.

EDIT È stata modificata la moltiplicazione e la divisione perché la divisione intera è un male (grazie a @JonathanAllan per averlo notato)

EDIT -1 byte Modificato i().index('^')in i().find('^')(grazie a @JonathanAllan [di nuovo!])


Dovresti scambiare la moltiplicazione e la divisione poiché la divisione è divisione intera - vale a dire a=[w[1]*R/I,w[0]*I/R](un semplice esempio che non funzionerebbe sarebbe un 1e 2con Ied Rentrambi 3). Attualmente 194 non 184 tra l'altro poiché le newline contano come byte ciascuna, ma je kcostano più byte di quanti ne salvino.
Jonathan Allan,

Puoi usare I=i().find('^'), e la forma abbreviata di __repr__, i backtick per fare l'ultima riga print`w[0]`+' '*(W-len(`w`)+4)+`w[1]`+'\n'+'-'*W+'\n'+' '*I+'^'e scendere a 182 - repl.it/EW8f
Jonathan Allan

0

C ++ 14, 482 byte

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;}

versione più leggibile:

#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 byte (riferimento ridotto a icona)

Ho appena minimizzato il riferimento, dato che sono molto nuovo nel golf del codice.

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 usi esattamente come nell'esempio, ma la funzione è sinvece di balance_seesaw.


Le linee 5 e 6 potrebbero diventare w[o>p]=[o//k,p//t][o>p]. Inoltre, la maggior parte delle linee potrebbe essere unita per liberare spazio extra.
James,

Grazie, come ho detto, sono molto nuovo, quindi trascuro anche le soluzioni più semplici.
ender_scythe

Tranne che non funziona, fornendo invece 0,56 invece di 196,56.
ender_scythe
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.