Fügen Sie Gewicht zu einer Seite einer Wippe hinzu, um es auszugleichen

13

Balanceakt

Eine Wippe (angeblich aus dem Französischen 'ci-ça', was 'das-das' bedeutet) bildet zusammen mit der ebenfalls allgegenwärtigen Rutsche und Schaukel ein Drittel der heiligen Dreiheit der Spielgeräte. Eine Wippe ist dann und nur dann perfekt im Gleichgewicht, wenn die Summe der Momente auf jeder Seite gleich ist. Eine Wippe kann daher ausgeglichen werden, indem der Seite mit der unteren Momentensumme eine bestimmte Gewichtsmenge hinzugefügt wird; Dies zu erreichen ist Ihr Ziel für diese Herausforderung.

Herausforderung

Ihre Herausforderung besteht darin, eine Darstellung einer Wippe als Eingabe zu nehmen und sie erneut auszugeben, wobei das Gewicht an einem Ende der Wippe zum Ausgleich hinzugefügt wird.

Eingang

Ihr Programm muss in einem angemessenen Format eine ASCII-Wippe wie die folgende haben:

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

Die erste Zeile enthält zwei Zahlen, die jeweils die Gewichte auf der Wippe darstellen. Auf jeder Seite befindet sich genau ein Gewicht, das jeweils ganz am Ende der Dielenseite angreift. Gewichte sind garantiert ganze Zahlen und stimmen immer mit dem entsprechenden Ende der Diele überein. Diese Zahlen überschneiden sich niemals mit dem Drehpunkt ( ^).

Die zweite Linie repräsentiert das "Brett" der Wippe. Jeder Bindestrich ( -) steht für die gleiche Länge wie jeder andere Bindestrich, mit Ausnahme des Bindestrichs direkt über dem Drehpunkt ( ^), der keine Länge hat.

Die dritte Linie repräsentiert den Drehpunkt der Wippe. Dieser Drehpunkt wird durch das einzige Zeichen markiert, das in dieser Zeile kein Leerzeichen ist, sondern ein Zirkumflex ('^'). Der Drehpunkt kann an einer beliebigen Stelle entlang der Länge der Diele in einer gültigen Eingabe positioniert werden, solange genügend Platz vorhanden ist, damit die Zahlen, die die Gewichte darstellen, den Drehpunkt weder in der Eingabe noch in der Ausgabe überlappen.

Die Eingabe hat garantiert drei Zeilen und darf vor oder nach den Zeichen, aus denen die Wippe besteht, keine Leerzeichen enthalten (mit Ausnahme der dritten Zeile, für die dies erforderlich ist).

Ausgabe

Für die Ausgabe sollte dieselbe Wippe-Darstellung auf Standard gedruckt werden, wobei jedoch eines (und nur eines) der Gewichte durch ein größeres Gewicht ersetzt wird, um die Wippe auszugleichen. Eingaben machen dies garantiert nur mit ganzen Zahlen möglich. Daher müssen Gewichte ohne Dezimalstellen oder ähnliche Bezeichnungen angegeben werden. Wenn Ihre Sprache nicht stdout verwendet, sollten Sie bei der Ausgabe nach Community- / Metakonsens vorgehen. Nachgestellte Zeilenumbrüche sind in Ordnung, andere Änderungen am Darstellungsformat sind jedoch wahrscheinlich nicht in Ordnung.

Veranschaulichung

Testeingänge und entsprechende Ausgänge

Eingang 1

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

Ausgang 1

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

Eingang 2

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

Ausgang 2

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

Eingang 3

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

Ausgang 3

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

Eingang 4

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

Ausgang 4

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

Referenzimplementierung - 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",
                "-------------------",
                "    ^              "])

Regeln

  • Dies ist , so dass der kürzeste Code-Gewinn in Bytes gezählt wird. Überprüfen Sie das Meta, wenn das Zählen von Bytes in Ihrer Sprache umständlich ist.

  • Es gelten Standardregeln / Regelungslücken.

  • Die Eingabe muss in einem angemessenen Format erfolgen. Eine nicht erschöpfende Liste geeigneter Formate wird wie folgt angegeben:

    • Eine einzelne Zeichenfolge mit durch Zeilenumbrüche getrennten Zeilen
    • Eine Liste von Zeichenfolgen, wobei jede Zeichenfolge eine Zeile darstellt
    • Ein 2D-Array oder eine Matrix von Zeichen

Verwandte Herausforderungen


FourOhFour
quelle
Gibt es einen Grund, warum die Ausgabe auf stdout erfolgen soll? Generell erlauben wir die Ausgabe von Funktionen über ihren Rückgabewert.
corvus_192
@ corvus_192 Ich sah dies als Herausforderung vom Typ "Anzeige" an, wie eine ASCII-Grafik oder "Zeichne eine Flagge" oder was auch immer. Eine Liste von Strings als Ausgabe ist als solche nicht wirklich "menschfreundlich". Wenn eine Sprache keine eingebaute Standardausgabe unterstützt, sind andere Ausgabeformen zulässig.
FourOhFour
Willkommen bei PPCG! Schöne erste Herausforderung. (und Requisiten für die Verwendung des Sandkastens auch darauf!)
AdmBorkBork
@TimmyD danke, es hat Spaß gemacht zu sehen, wie die Leute das Problem angehen.
FourOhFour

Antworten:

5

05AB1E ,60 51 50 49 47 45 Bytes

Dank Emigna 10 Byte und dank Adnan 1 Byte gespart.

Alle Eingabezeilen müssen die gleiche Anzahl von Zeichen enthalten.

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

Probieren Sie es online!

Es sollte eine Faustregel geben: "Wenn Ihr 05AB1E-Code länger als 40 Byte ist, machen Sie es wahrscheinlich falsch." Es scheint so golffähig, jede Idee ist willkommen!

Osable
quelle
1
Zum einen ¬s¤s\‚kann sein õK.
Emigna
1
kD²g->(‚kann sein, ¡€gwenn Sie die fehlenden Leerzeichen in der unteren Reihe des Testfalls
hinzufügen
1
Danke für die Erklärung. Ich sehe, dass es dem Referenzalgorithmus ziemlich ähnlich ist (keine schlechte Sache), aber es gibt auch einige clevere Tricks. Etwas über 05AB1E bedeutet, dass es klügere Antworten zu bieten scheint als einige andere Golfsprachen - es ist vielleicht mein Favorit, besonders wenn es eine beiliegende Erklärung gibt.
FourOhFour
1
Gute Antwort! Sie können ersetzen 31SÍmit 1®‚:)
Adnan
1
Kannst du vielleicht auch / ïmit ÷. Ersetzen ?
Emigna
5

JavaScript (ES6), 136

Funktioniert wahrscheinlich nicht in Chrome, da es destrukturierte Zuweisungen und Standardparameter verwendet.

Beachten Sie, dass die Standard-JS-Ausgabemethode alertaufgrund der verwendeten proportionalen Schriftart für die Aufgabe besonders ungeeignet ist.

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

Weniger golfen

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

Prüfung

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>

edc65
quelle
Laut kangax.github.io/compat-table/es6 unterstützt Chrome 54 die Standardparameter und die Destrukturierung vollständig, sodass Sie sich keine Sorgen machen müssen.
ETHproductions
Funktioniert in Chrome für mich.
DLosc,
3

Perl, 149 + 2 = 151 Zeichen

Erfordert Befehlszeilenoptionen -p0(dies führt zu einer 2-Byte-Strafe auf die 149 Byte im Programm selbst).

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

Erläuterung:

  • Der -p0Switch liest den gesamten Eingang bis zum ersten NUL-Byte oder EOF. Dieses Problem lässt keine NULs zu, daher erhalten wir standardmäßig die gesamte Eingabe in der Variablen $_, die für reguläre Ausdrücke usw. verwendet wird.
  • Wir beginnen mit einem regulären Ausdruck, der die Eingabe analysiert (zwischen dem ersten und dem zweiten Schrägstrich). Es gibt verschiedene Möglichkeiten, wie wir das erste Gewicht (z. B. .+?) analysieren können, aber ich kann es nicht unter 3 Zeichen bringen, also kann ich auch das Offensichtliche verwenden \d+. Die zweite Zahl steht am Ende der Zeile und kann als .+(2 Zeichen) analysiert werden . Die Mittellinie bestimmt, wie breit die Skalen sind. Es wird analysiert als -+(viele andere Darstellungen würden funktionieren). Die Leerzeichen vor dem Caret in der letzten Zeile sind +. Sobald das Caret (oder in der Tat ein Nicht-Leerzeichen) erscheint, ignorieren wir den Rest der Eingabe.
  • Perl erfaßt automatisch die vier Gruppen des regulären Ausdrucks (erstes Gewicht, zweites Gewicht, Reihe von Bindestrichen, Leerstellen, bevor die caret) in $1, $2, $3, $4. Wenn Sie einen regulären Ausdruck als Argument angeben, wird mapzusätzlich ein Array dieser Gruppen als Array für die Zuordnung verwendet. Wir nehmen deshalb ihre Längen; Dies ist ein bequemer Weg , um die Längen zu speichern , $3und $4ohne schreiben lengthzweimal. Wir überschreiben auch $_mit der Länge von $1; wir kümmern uns nicht wirklich um den Wert davon (die Anzahl der Ziffern in der linken Eingabe ist irgendwie nutzlos), aber die Tatsache, dass es kurz ist ( $_die Länge ist jetzt die Anzahl der Ziffern in der Anzahl der Ziffern in der erstes Gewicht, das im Vergleich zur Breite der Waage unbedingt sehr klein ist).
  • Wir messen das Verhältnis, $rin das die Skalen unterteilt sind.
  • $1*$r>$2prüft, welche Seite schwerer ist. Wir speichern die neuen Gewichte in $xund $y; Diese haben sehr einfache Berechnungen, sobald das Gewichtsverhältnis bekannt ist.
  • Wir verketten $x, $,und $yin $_, um die oberste Zeile zu erzeugen , und fügen dann weiterhin Leerzeichen hinzu ( $"enthält standardmäßig ein einzelnes Leerzeichen und ist kürzer als ein Literal-Leerzeichen ' '), $,bis es die gleiche Länge wie die mittlere Zeile hat (dh Länge hat $c). (Wählte ich die Variable , $,da es eine ist integrierte Variable , die sicher in diesem Zusammenhang geändert werden kann und startet standardmäßig leer) . Wie lengthauf arbeitet $_standardmäßig wir brauchen es nicht explizit ein Argument zu geben. Ich habe eine Yoda-Bedingung verwendet, da für das korrekte Parsen eine deutlich weniger eindeutige Syntax erforderlich ist.
  • Schließlich definiere ich Perls Idee der Ausgabezeilen-Endungskonvention ( $\) neu, um den Rest des Skalensatzes zu enthalten (der derselbe wie in der Eingabe ist, sodass ich den Großteil einfach $3und $4direkt verwenden kann). Beachten Sie, dass dies bedeutet, dass in der dritten Zeile kein nachgestelltes Leerzeichen steht. das Hinzufügen würde das Programm etwas länger machen und scheint keinen Zweck zu erfüllen, also habe ich es weggelassen.
  • Am Ende des Programms -plöst der Schalter erneut aus; Dieses Mal wird $_gefolgt von einer "newline" ( $\) ausgegeben . Da ich den Zeilenvorschub für die Ausgabe neu definiert habe, erzeugen diese beiden impliziten Ausdrucke den neuen Skalensatz zwischen ihnen (obwohl es als Nebeneffekt keinen Zeilenvorschub für die Ausgabe gibt).
  • Der -pSwitch versucht nun erneut, die Eingabe zu lesen, aber wir haben bereits die gesamte Datei verschluckt, sodass EOF gelesen und das Programm beendet wird.

quelle
1

PHP, 212 209 205 Bytes

wahrscheinlich golfen

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

Übernimmt Eingaben vom Kommandozeilenargument; Flucht vor Zeilenumbrüchen. Laufen Sie mit -r.


Das Ersetzen durch einen Platzhalter funktionierte nicht wie erwartet. Also musste ich der ersten Regex mehr Parens hinzufügen.

Titus
quelle
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_"^",@>>

Probieren Sie es online!

James Holderness
quelle
215 Bytes , denke ich
Zacharý
@ Zacharý Ich fürchte nicht. Mindestens einer dieser Pfeile wird benötigt, da er sonst immer dann ausfällt, wenn das linke Drehmoment> das rechte Drehmoment ist (zum Beispiel der erste Testfall). Der andere wurde >meiner Meinung nach nur aus ästhetischen Gründen gelassen. Das heißt, ich habe anscheinend eine 215-Byte-Lösung in meinen Notizen, so dass es möglich sein könnte (es gibt auch Fehler, die erklären, warum ich sie nie eingereicht habe - ich habe jetzt keine Zeit, sie zu testen).
James Holderness
1

Python 2 184 183 Bytes

Auf jeden Fall golfen

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

Ziemlich einfach. Nehmen Sie einfach die angepassten Gewichte zum Anpassen beider Seiten, sehen Sie, welche größer als das Original sind, und ändern Sie diese und geben Sie sie aus.

EDIT Multiplikation und Division umgeschaltet, da Integer-Division nicht sinnvoll ist (danke an @JonathanAllan, der dies bemerkt hat)

EDIT -1 Byte geändert i().index('^')in i().find('^')(danke an @JonathanAllan [nochmal!])

HyperNeutrino
quelle
Sie sollten die Multiplikation und Division vertauschen, da es sich bei der Division um eine Ganzzahldivision handelt a=[w[1]*R/I,w[0]*I/R](ein einfaches Beispiel, das nicht funktionieren würde, wäre a 1und 2with Iund Rboth 3). Derzeit 194 übrigens nicht 184, da die Zeilenumbrüche jeweils als Byte zählen, sondernj und kkosten mehr Bytes als sie speichern.
Jonathan Allan
Sie können verwenden I=i().find('^')__repr__ Backticks und die Kurzform von Backticks verwenden, um die letzte Zeile zu machen print`w[0]`+' '*(W-len(`w`)+4)+`w[1]`+'\n'+'-'*W+'\n'+' '*I+'^'und zu 182 zu gelangen - 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;}

lesbarere Version:

#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;
}
Bobas_Pett
quelle
0

Python 3, 235 230 Bytes (minimierte Referenz)

Ich habe die Referenz nur minimiert, da ich mit Code-Golfen noch nicht viel anfangen kann.

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

Sie verwenden es genauso wie im Beispiel, aber die Funktion ist s statt balance_seesaw.

ender_scythe
quelle
Zeilen 5 und 6 könnten werden w[o>p]=[o//k,p//t][o>p]. Außerdem können die meisten Zeilen verbunden werden, um zusätzliche Leerzeichen zu entfernen.
DJMcMayhem
Danke, wie gesagt, ich bin sehr neu und übersehe selbst die einfachsten Korrekturen.
ender_scythe
Außer, es funktioniert nicht, stattdessen 0,56 statt 196,56.
ender_scythe