Fallende ASCII-Kugeln

16

Eingang

Sie erhalten eine 2D-Karte mit Kugeln und Boden. Es sieht aus wie das:

  1         5          2
                 3
     4


__________________________

Jede Zahl ist eine Kugel und die _ist bodennah. Der Unterstrich _ist in keiner anderen Zeile als der bodenebenen Zeile zulässig. Oberirdisch sind nur Leerzeichen, Zeilenumbrüche und Ziffern 0-9zulässig. Sie können nicht davon ausgehen, dass die letzte Zeile die Bodenebene ist - leere Zeilen unterhalb der Bodenebene sind zulässig. Sie können auch Leerzeichen hinzufügen, um leere Zeilen zu füllen, wenn dies Ihnen hilft.

Bälle können Nummern von 0bis haben 9, können übereinander platziert werden, aber nicht unter der Erde. Die Ballnummern sind eindeutig.

Angenommen, jedes Zeichen entspricht einem Meter .

Get map from pastebin!
Testfall 1 - sollte so etwas wie diesen ausgeben.
Testfall 2 - sollte die gleichen Ergebnisse wie die erste Karte liefern

Herausforderung

Ihre Herausforderung besteht darin, eine Karte wie diese aus einer Datei oder stdin- Sie dürfen sie verwenden cat balls.txt | ./yourexecutable- aus der Ausgabegeschwindigkeit jedes Balls zu lesen, wenn er auf den Boden trifft.

Hier ist die Formel für die Geschwindigkeit:

Bildbeschreibung hier eingeben

Angenommen, dies hist die Differenz der Liniennummer zwischen der Liniennummer des Bodens und der Liniennummer des Balls, und diese ist ggleich 10m/s^2.

Ausgabe

Sie sollten die Anzahl und Geschwindigkeit der einzelnen Bälle in m/sBodennähe ausgeben . Zum Beispiel N - Vm/s, wo Nist die Ballnummer und Vist seine Geschwindigkeit. Sie können auch ein Array ausgeben, wenn Sie möchten.

Viel Spaß beim Codieren! :)

Jacajack
quelle
Testfälle ohne erwartetes Ergebnis sind keine Testfälle
edc65
@ edc65 Ich habe der Frage die erwarteten Ergebnisse hinzugefügt
Jacajack
Ist es in Ordnung, wenn ich das Verzeichnis als Eingabe vom Benutzer als Teil des Programms nehme?
Daniel
@Dopapp Was meinst du genau?
Jacajack
Siehe meine Antwort .
Daniel

Antworten:

8

MATL , 31 30 27 25 Bytes

95\16\5B#fG&X>1)b- 20*X^h

Eingabe ist ein 2D-Zeichen-Array mit ;als Zeilentrennzeichen:

['  1         5          2  ';'                 3        ';'     4                    ';'                          ';'                          ';'__________________________']

Probieren Sie es online! Oder fügen Sie eine Initiale tin den Code ein , um die Karte übersichtlicher anzuzeigen.

Hier sind die anderen Testfälle: erstens , zweitens .

Erläuterung

95\      % Take input implicitly. Modulo 95: convert to numbers and map '_' into 0
16\      % Modulo 16: map space into 0 and digit chars into corresponding numbers
5B#f     % Find row indices and values of nonzero entries
G        % Push input again
&X>      % Index of maximum of each column. This finds character '_'
1)       % Get first value (they are all equal)
b        % Bubble row indices of numbers up in the stack
-        % Subtract to get distance from each number to the ground
20*X^    % Multiply by 20, take sqrt. This gives the velocity values
h        % Horizontally concat numbers and velocities. Display implicitly
Luis Mendo
quelle
7

C, 125 122 121 Bytes

b[99]={};main(l,c){for(;(c=getchar())<95u;)b[c]=(l+=c==10);for(c=47;++c<58;)b[c]&&printf("%c,%f\n",c,sqrt((l-b[c])*20));}

Kompilieren und ausführen mit gcc -w golf.c -lm && cat balls.txt | ./a.out.

orlp
quelle
Das ist wirklich toll, Sir! Das habe ich in meiner Frage nicht gesagt, aber ich möchte, dass Sie wissen, dass Ihr Beispiel nichts ausgibt, wenn ein anderes Zeichen als 0 ... 9in einer Textdatei vorkommt. Wie auch immer, +1, weil es meine Schuld ist, nicht darauf hinzuweisen
Jacajack
@Jacajack Nein, jedes Zeichen ist in Ordnung, solange es kein Zeichen enthält, dessen ASCII-Code größer als ist _. Dies könnte jedoch mit einem zusätzlichen Byte ( !=anstelle von <) behoben werden .
Orlp
Nun, ich habe 'x' zum Testen verwendet. Keine Ursache. Dein Code ist großartig :)
Jacajack
@Jacajack In der neuen Version ist es kein Ein-Zeichen-Fix mehr, aber ich habe 3 weitere Bytes gespart :)
orlp
Nett! :) Ich werde nachsehen, was ich mit meinem Code machen kann, wenn ich nach Hause komme. Ich weiß, es kann viel gekürzt werden, aber ich möchte nicht, dass es eine Kopie von Ihnen ist: p
Jacajack
6

C - 194 (-5) 150 137 Bytes

Mit ein bisschen mehr Zeit und Nachdenken habe ich 44 Bytes abgespielt.
Dank orlp, das mir geholfen hat, 13 Bytes zu sparen

Ich beginne mit meinem C-Code:

b[256]={},n,i=47;main(l,c){for(;~(c=getchar());n=c==95?l:n)b[c]=(l+=c==10);for(;++i<58;)b[i]&&printf("%d %f\n",i-48,sqrt((n-b[i])*20));}

Und für Menschen lesbare Version:

//Throws many warnings, but lack of libraries is tolerated

/*
    c - current character
    l - line number (starts at 1)
    n - ground level
    i - iterator
    b - balls array
*/

b[256] = {}, n, i = 47; //That actually works, as long as you are using ASCII

main( l, c )
{
    for ( ;~( c = getchar( ) ); n = c == 95 ? l : n ) //Read stdin and search for ground
        b[c] = ( l += c == 10 ); //Increment lines counter on newlines, and save line numbers

    for ( ; ++i < 58; ) //Iterate through balls
        b[i] && printf( "%d %f\n", i - 48, sqrt( ( n - b[i] ) * 20 ) ); //Print out data    
}

Kompiliere und starte so: gcc -o balls ballsgolf.c -lm && cat 1.txt | ./balls

Ausgabe

1 10.000000
2 10.000000
3 8.944272
4 7.745967
5 10.000000
Jacajack
quelle
4 Bytes speichern: ~(c=getchar())statt (c=getchar())!=EOF.
Marinus
@marinus Das hatte ich.
Orlp
1
if (x != -1)ist dasselbe wie if (~x)(auf Zweierkomplement-Maschinen), weil ~-1es (eindeutig) ist 0. In C niemals Golf spielen while(cond), da for(;cond;)es genauso lang ist und mehr Möglichkeiten zum Golfen bietet. In Ihrem Beispiel kann dies werden for(;~(c=getchar());n=c==95?l:n)b[c]=(l+=c==10);.
Orlp
@orlp Ich verstehe, danke für den Rat :)
Jacajack
1
l=1Sie können dies umgehen, indem Sie ldas erste Argument für eingeben main, da die C-Laufzeit die Anzahl der Argumente an main als erstes Argument ( argc) übergibt und Sie dann ein Programm ohne Befehlszeilenargumente ( ./a.out) aufrufen argc = l = 1. n=0;ist unnötig, da globale Ganzzahlen automatisch auf 0 initialisiert werden. Es reicht also n;aus.
Orlp
4

Pyth, 27 26 25 24 Bytes

smf-hT "_" .e, b @ * 20-xd \ _k2dC 
smf @ hT`M; .e, b @ * 20-xd \ _k2dC 
smf @ T`M; .e, b @ * 20-xd \ _k2dC
sm @ # `M; .e, b @ * 20-xd \ _k2dC

Probieren Sie es online!

Undichte Nonne
quelle
@orlp Oh, ich dachte der Boden kann nur in der letzten Zeile sein.
Undichte Nonne
@orlp Nein, das tut es nicht
Leaky Nun
1
@orlp Es war in den Regeln, dass "Sie Leerzeichen hinzufügen können, um leere Zeilen zu füllen, wenn das Ihnen hilft."
Undichte Nonne
3

Matlab, 100 96 89 90 Bytes

s=input('');X=find(s==95);for i=0:9
[x y]=find(s==48+i);if(x)[i sqrt(20*(X(1)-x))]
end
end

Viele Bytes dank Luis Mendo gespeichert

Eingabeformat:

['  1         9          2  ';'                 3        ';'     4                    ';'                          ';'                          ';'__________________________']

Erläuterung:

X=find(s==95)         -- finds '_', we'll need X(1) to determine max height
for i=0:9             -- loops through balls' numbers
[x y]=find(s==48+i)   -- finds the ball
if(x)                 -- if it is present
[i sqrt(20*(X(1)-x))] -- output its number and velocity
pajonk
quelle
3

Python 3, 84 Bytes

Version 6, 84 Bytes: (Danke an Leaky Nun!)

lambda a:[(c,(~-(len(a)-i)*20)**.5)for i,s in enumerate(a)for c in s if c.isdigit()]

Version 5, 91 Bytes:

lambda a:[c+":"+str((~-(len(a)-i)*20)**.5)for i,s in enumerate(a)for c in s if c.isdigit()]

Version 4, 92 Bytes:

lambda i:[c+":"+str((~-(len(i)-n)*20)**.5)for n in range(len(i))for c in i[n]if c.isdigit()]

Version 3, 99 Bytes:

def r(i):x=len(i);print([c+":"+str((~-(x-n)*20)**.5)for n in range(x)for c in i[n] if c.isdigit()])

Version 2, 102 Bytes:

def r(i):
 n=len(i)
 for l in i:
  for c in l:
   if c.isdigit():print(c+":"+str((~-n*20)**.5))
  n-=1

In den obigen Versionen wird ein Array von Zeichenfolgen als Eingabe verwendet.

Version 1, 140 Bytes:

with open(input(),"r")as i:
 n=sum(1for l in i);i.seek(0)
 for l in i:
  for c in l:
   if c.isdigit():print(c+":"+str((~-n*20)**.5))
  n-=1

Dies übernimmt das Verzeichnis der Datei als Eingabe vom Benutzer.

Daniel
quelle
1 for l in i->1for l in i
Undichte Nonne
@LeakyNun, funktioniert dieser Trick mit allen Schlüsselwörtern und Zahlen?
Daniel
1
Ich glaube schon Also, (n-1)*20->~-n*20
Undichte Nonne
1
Warten Sie mal. Benötigt Python3 beim printAufruf keine Klammern ?
Yytsi
1
@LeakyNun Nein, es funktioniert nicht für alle Schlüsselwörter und Zahlen in Python 2. Es funktioniert speziell nicht für Schlüsselwörter, die mit einem beginnen e, da der Python-Tokenizer dann versucht, sie als wissenschaftliche Gleitkommanotation zu analysieren (z 1e5. B. ). Beispiel , das nicht: f = lambda n:-1if n<0else 1. Ein Beispiel, das in beiden Python-Versionen fehlschlägt, ist 0or 1, weil der Tokenizer denkt, dass 0oeine Oktalzahl beginnt.
Orlp
2

Python 3, 84 Bytes

lambda x:[[i,(20*x[x.find(i):x.find('_')].count('\n'))**.5]for i in x if i.isdigit()]

Eine anonyme Funktion, die die Eingabe von Argumenten als mehrzeilige Zeichenfolge akzeptiert, wobei alle Leerzeilen mit Leerzeichen gefüllt sind, und ein Array zurückgibt, in dem jedes Element die Form [Ballnummer, Geschwindigkeit] hat.

Wie es funktioniert

lambda x                      Function with input x
...for i in x if i.isdigit()  Loop through all characters i in x for which i is a digit,
                              and hence one of the balls
x[x.find(i):x.find('_')]      Slice x to give the substring between the ball and the ground
....count('\n')               Count the number of newlines in the substring to give the
                              height of the ball
(20*...)**.5                  Calculate the speed of the ball as it hits the ground
[i,...]                       Package the ball number and speed into a list
:[...]                        Return all ball-speed pairs as a list with elements [ball
                              number, speed]

Probieren Sie es auf Ideone

TheBikingViking
quelle
In diesem Fall, denke ich, handelt es sich eher um ein Code-Snippet als um ein eigenständiges Python-Skript, nicht wahr?
Jacajack
@Jacajack Dies ist in der Tat eine Funktion, kein Snippet, was standardmäßig erlaubt ist . In Python sind Lambda-Funktionen Funktionen ohne Namen, die einer Variablen zugewiesen und bei Bedarf aufgerufen werden können. Sie könnten schreiben f = MyAnswerund dann mit anrufen f(x). Es besteht Einigkeit darüber, dass es nicht notwendig ist, Lambdas zu nennen . Übrigens eine schöne Herausforderung!
TheBikingViking
Klar, ich dachte nur, Lambdas wären hier vermutlich Code-Schnipsel ( meta.codegolf.stackexchange.com/a/1146/55729 ). Dann ist wohl alles in Ordnung. Vielen Dank für Ihre Meinung :)
Jacajack
2

JavaScript (ES6) 93

Bearbeiten 2 Bytes, die dank @Jacajack gespeichert wurden

Eine Funktion mit einem mehrzeiligen String als Eingabeparameter. Die Ausgabe wird nicht sortiert (da dies nicht angefordert wird)

a=>[...a].reverse().map(c=>c>'Z'?b=i:c<' '?++i:c>' '&&console.log(c,Math.sqrt((i-b)*20)),i=0)

Prüfung

F=
a=>[...a].reverse().map(c=>c>'Z'?b=i:c<' '?++i:c>' '&&console.log(c,Math.sqrt((i-b)*20)),i=0)

function test()
{
  F(I.value);
}

test()
#I { height: 12em; width: 30em}
<textarea id=I>
    
 
  1         5          2
                 3
     4


__________________________




</textarea>
<button onclick="test()"></button>

edc65
quelle
Wäre nicht sqrt(x)kürzer als pow(x,.5)?
Jacajack
@Jacajack ja, danke, ich weiß nicht, wie mir das durch den Kopf ging
edc65