Das Golfer-Abenteuer - Kapitel 1: Die Vase

13

Das Golfer-Abenteuer

Dies ist die erste Herausforderung! Es wird später mehr Herausforderungen geben, die Daten von der vorherigen Herausforderung erfordern :)

Kapitel 1: Die Vase

Stellen wir uns eine Minute vor. Sie sind ein mächtiger Gott, Ihre Kräfte sind grenzenlos, erfordern jedoch eines: Seelen. Jede Seele wird hier durch ein Byte dargestellt, jedes Byte, das Sie verwenden, opfert eine Seele. Das Ziel ist also offensichtlich, die größte Menge an Menschen zu retten und gleichzeitig die geringste Menge an Seelen zu opfern.

Ihre erste Herausforderung besteht darin, ein kleines Dorf zu retten. Der Teufel ist bereit, nicht das gesamte Dorf zu zerstören, wenn Sie seine Herausforderung lösen.

Die Herausforderung :

Sie haben eine vertikale Vase, die genau 10 Dinge enthalten kann (inklusive Luft). Wenn Sie etwas in diese Vase geben, wird das Ding durch die Schwerkraft auf den Boden fallen. Wenn die Vase bereits voll ist (und wenn Sie sie als "voll mit Luft" betrachten, ist sie immer voll), ersetzt der Eingang das Element am oberen Rand der Vase.

Hier ist die Menge der erlaubten Dinge:

  • Luft 0 /
  • Ein Stein 1 / -
  • Ein Blatt 2 / ~
  • Eine Bombe 3 / x

Wenn sich ein Stein oder ein Blatt auf "A Bomb" befindet, wird es explodieren und das Ding auf der Oberseite zerstören.

Die Eingabe ist die Liste der Dinge, die Sie in jeder Runde in die Vase setzen.

Beispiel: 11231: Du legst 2 Steine, dann ein Blatt, dann eine Bombe und schließlich einen letzten Stein.

Wenn die Vase statisch ist, können Sie mit der folgenden Regel zu zählen beginnen:

  • Rock fügt dem Akku 1 Einheit hinzu
  • Blatt multipliziert den Akku mit 2
  • Bombe dekrementiert den Akku um 1
  • Luft macht nichts

(Sie müssen von der Oberseite der Vase zu zählen beginnen)

Hier ist die Simulation, die wir mit "11231" als Eingabe erhalten:

|-|  |-|  |~|  |x|  |-|  | |  | |  | |  | |  | |  | |
| |  |-|  |-|  |~|  |x|  |-|  | |  | |  | |  | |  | |
| |  | |  |-|  |-|  |~|  |x|  |-|  | |  | |  | |  | |
| |  | |  | |  |-|  |-|  |~|  |x|  |-|  | |  | |  | |
| |  | |  | |  | |  |-|  |-|  |~|  |x|  |-|  | |  | |
| |  | |  | |  | |  | |  |-|  |-|  |~|  |x|  |-|  | |
| |  | |  | |  | |  | |  | |  |-|  |-|  |~|  |x|  | |
| |  | |  | |  | |  | |  | |  | |  |-|  |-|  |~|  |~|
| |  | |  | |  | |  | |  | |  | |  | |  |-|  |-|  |-|
| |  | |  | |  | |  | |  | |  | |  | |  | |  |-|  |-|

Und die Ausgabe wird 2 (berechnet als ((0 x 2) + 1) + 1) sein. Es müssen nicht alle Zustände der Vase gedruckt werden!

Das Basisprogramm (Python3)

Sie können es ausführen, um zu verstehen, wie es funktioniert.

def printVase(vase):
  for i in vase:
    if i == 1:
      print("|-|")
    elif i == 2:
      print("|~|")
    elif i == 3:
      print("|x|")
    else:
      print("| |")

def updateVase(vase):
  changed = False
  for i in range(len(vase), -1, -1):
    if i < len(vase) - 1:
      if vase[i+1] == 3 and vase[i] in [1,2]:
        vase[i], vase[i+1] = 0, 0
        changed = True
      if not vase[i+1] and vase[i] in [1, 2, 3]:
        vase[i], vase[i+1] = vase[i+1], vase[i]
        changed = True
  return changed

userInput = input("Vase : ")
vase = [0 for i in range(0, 10)]
oldVase = vase
while updateVase(vase) or userInput != "":
  if userInput != "":
    vase[0] = int(userInput[0])
  userInput = userInput[1::]
  printVase(vase)
  input()

accumulator = 0
for i in vase:
  if i == 1:
    accumulator += 1
  if i == 2:
    accumulator *= 2
  if i == 3:
    accumulator -= 1
print(accumulator)

Golf-Version (Python3, kein Vase-Display): 360 Bytes = 360 Punkte

def u(v):
  c=0
  for i in range(len(v),-1,-1):
    if i<len(v)-1:
      if v[i+1]==3 and v[i]in[1,2]:v[i],v[i+1],c=0,0,1
      if not v[i+1]and v[i]in[1,2,3]:v[i],v[i+1],c=v[i+1],v[i],1
  return c
l,v=input(),[0 for i in range(0, 10)]
while u(v)or l!="":
  if l!="":v[0],l=int(l[0]),l[1::]
a=0
for i in v:
  if i==1:a+=1
  if i==2:a*=2
  if i==3:a-=1
print(a)

Wenn Sie testen möchten, ob Ihr Programm ordnungsgemäß funktioniert, können Sie die folgende Eingabe testen: 12122111131

Richtige Antwort ist 43 :) (Danke Emigna)

Nun zu den Punkten:

  • (x) Punkte, bei denen: x die Anzahl der zum Schreiben Ihres Programms benötigten Bytes ist. Wenn Sie nach dem Posten der nächsten Herausforderung antworten, werden Punkte für diese Herausforderung nicht zu Ihrer Gesamtpunktzahl hinzugefügt.

Ziel ist es, während der gesamten Herausforderung eine Mindestpunktzahl zu erhalten :) Wenn Sie einen Teil der Herausforderung überspringen, erhalten Sie standardmäßig (wx + 1) Punkte für den übersprungenen Teil (wobei wx die schlechteste Punktzahl ist) für diese Herausforderung).

Daten, die für die nächste Herausforderung benötigt werden:

Ausgabe bei Eingabe = 10100000200310310113030200221013111213110130332101

Aktueller Champion: Emigna

Allen viel Glück !

Sygmei
quelle
2
Was ist mit der "kann genau 10 Dinge enthalten"? Zählt "Luft"? Ist die Eingabe garantiert so, dass die Vase nur 10 Dinge enthält (ich sehe, dass es in der Referenzimplementierung nicht berücksichtigt wird)? Auch der Eingang, der die Daten für die nächste Herausforderung erzeugt, scheint mehr als 10 Dinge zu haben (selbst wenn Luft wie nichts ist und Bomben die nächste Sache über der Luft in die Luft jagen, wird es 14 Dinge geben, denke ich).
Jonathan Allan
1
Ein Eingang bildet 333eine Vase [0, 0, 0, 0, 0, 0, 0, 3, 3, 3]in Ihrem Golf-Algorithmus und somit eine Punktzahl von -3, aber sollte es nicht [0, 0, 0, 0, 0, 0, 0, 0, 0, 3]eine Punktzahl -1sein, die Ihrer Spezifikation entspricht?
Laikoni
2
@Laikoni Ich habe vergessen anzugeben, dass Bomben nicht explodieren, wenn eine Bombe auf einer anderen liegt, danke!
Sygmei
1
Die Ausgabe für 10100000200310310113030200221013111213110130332101 scheint 22 zu sein, oder?
Erik der Outgolfer
2
Es könnte eine gute Idee sein, einen kniffligen Testfall wie 12122111131 hinzuzufügen .
Emigna

Antworten:

5

Python 2 - 208 191 185 180 172 164 156 Bytes

t=filter(bool,map(int,input()))
i=a=0
n=len(t)
while 0<n-1>i<11:
 if(t[i]>=3>t[i+1]):del t[i:i+2];i,n=0,n-2
 i+=1
for x in t[9::-1]:a+=a+x%2*(2-x-a)
print a

Der Zusammenbruch ist, dass Luft entfernt wird und die Bomben, wenn sie auf dem Stapel liegen, zählen.

BEARBEITEN: Ich habe zu Python 2 gewechselt, um ein Byte zu speichern, aber jetzt sollte die Eingabe in geschweiften Klammern wie '3312123' stehen.

EDIT2: Ich bin auch ein bisschen stolz auf die Anzahl der Akkus

EDIT3: Danke für all deine Vorschläge, ich hätte nie gedacht, dass ich es so niedrig bekommen könnte

Pâris Douady
quelle
Schöne erste Antwort! Ich habe auch mit Python nachgedacht, aber heute fehlte mir die Zeit. Denke, du hättest meinen Ansatz sowieso geschlagen.
ElPedro
Vielen Dank für den freundlichen Kommentar :) Zum ersten Mal mache ich Codegolf und ich muss sagen, dass es ziemlich viel Spaß macht.
Pâris Douady
Verwenden Sie t[:10][::-1]stattdessen reverse(), um 4 Bytes zu speichern, und verwenden Sie möglicherweise auch Python 2, um eine Klammer auf dem print? Zu speichern . Kommt zu 5 weiteren Seelen, die für mich gerettet wurden :)
ElPedro
Kein Python2 für mich, da ich input () umsetzen müsste, damit es funktioniert und 5 weitere Seelen töten würde. Schöner Fang auf der [:: - 1]
Pâris Douady
Übrigens habe ich in der Frage nichts gesehen, was besagt, dass die Eingabe in Anführungszeichen eingeschlossen werden kann. Sagt nur "Die Eingabe ist die Liste der Dinge". Funktioniert in Python 2 :)
ElPedro
4

05AB1E , 28 36 Bytes

05AB1E verwendet die CP-1252- Codierung.

Î0KDvT¹g‚£`sTØõ:žwõ:ì}ÁT£ÀRS"<>·"è.V

Probieren Sie es online!

Emigna
quelle
1
Beeindruckend wie immer: D Es wird schwer zu schlagen sein
Sygmei
2
T£ÀRS ->Tränen ->Ich weine in Ordnung ...
steenbergh
3

Python 2, 150 bis 146 Bytes

v=[]
s=0
for c in input():
 v=v[:9]
 if'0'==c:1
 elif 3 in v[-1:]and c in'21':v=v[:-1]
 else:v+=[int(c)]
for x in v[::-1]:s+=s+x%2*(2-x-s)
print s

Vielen Dank an Pâris Douady für die Punktformel und für das Speichern von 4 Bytes.

TFeld
quelle
Hast du meine Formel genommen, um den Punkt zu zählen? Wie auch immer, du hast mich geschlagen und es ist viel sauberer. Sie können auch einige Bytes sparen, indem Sie for c in input()direkt
Pâris Douady
2

Javascript, 267 264 249 Seelen geopfert

r='replace'
f=t=>{t=t[r](/0/g,'');while(/3[12]/.test(t.substring(0,10)))t=t[r](/3[12]/,'');
a=t.length-1;x=(t.substring(0,9)+(a>8?t[a]:'')).split('').reverse().join('');
c='c=0'+x[r](/1/g,'+1')[r](/2/g,';c*=2;c=c')[r](/3/g,'-1');eval(c);return c}

Bearbeitete Version, da die vorherige für größere Eingaben falsch war. Golfen Sie weiter, indem Sie einen string.prototype.replace()Funktionsaufruf mit Array-Zugriff ausführen . Erläuterung:

f=t=>{                                  Function declaration, input t
t=t.replace(/0/g,'');                   Remove air
while(/3[12]/.test(t.substring(0,10)))  Look for bombs; not double bombs, and only in the first 10 chars
    t=t.replace(/3[12]/,'');            Detonate bombs. If this makes a new bomb fall into the vase, or
                                        a double bomb is now a single bomb, it'll detonate that bomb too.
x=(t.substring(0,9)+                    Fill the vase, take the first 9 items
    (t.length>9?t[t.length-1]:''))      If we have more than 9 items, then add the last one
    .split('').reverse().join('');      Flip the instruction string.
c='c=0'+x.replace(/1/g,'+1')            Replace each item with the proper instruction to the ACC
         .replace(/2/g,';c*=2;c=c')
         .replace(/3/g,'-1');
eval(c);return c}                       Eval to get the value of ACC and return it.

f('11231');kehrt zurück 2. Probieren Sie es online aus

steenbergh
quelle
10100000200310310113030200221013111213110130332101 gibt das gute Ergebnis nicht zurück :) Du bist jedoch in der Nähe :)
Sygmei
@Sygmei Ich weiß, und ich habe den Mist aus ihm heraus debuggt, aber ich kann nicht herausfinden, warum. Können Sie mich im Chat sehen?
Steenbergh
1

Haskell, 221 202 181 177 166 Seelen Bytes

g(0:r)=r++[0]
g(3:x:r)|0<x,x<3=0:0:g r|1<3=3:g(x:r)
g(x:r)=x:g r
g r=r
v%(x:r)=g(init v++[x])%r
v%[]|v==g v=foldr([id,(+)1,(*)2,(-)1]!!)0v|1<3=g v%[]
(([0..9]>>[0])%)

Probiere es auf ideone aus . Nimmt Elemente als Ganzzahlliste.

Verwendung:

*Prelude> (([0..9]>>[0])%) [1,2,1,2,2,1,1,1,1,3,1]
43

(Edit: Old) Erklärung:

g [] = []                             -- g simulates gravity in the vase
g ('0':r) = r ++ "0"                  -- the first 0 from the bottom is removed
g ('3':x:r) | elem x "12" = "00"++g r -- if a 1 or 2 is on a bomb, explode 
            | True = '3' : g(x:r)     -- else continue
g (x:r) = x : g r                     -- no air and no bomb, so check next item

c x = [id,(+)1,(*)2,(-)1]!!(read[x])  -- map 0, 1, 2, 3 to their score functions

f v w (x:r) =                         -- v is the current vase state, w the previous one
               init v++[x]            -- replace last vase element with input
             g(init v++[x])           -- simulate one gravity step
           f(g(init v++[x]))v r       -- repeat, w becomes v
f v w[] | v==w =                      -- if the input is empty and vase reached a fixpoint
                 foldr c 0 v          -- then compute score 
        | True = f (g v) v []         -- else simulate another gravity step


vase input = f "0000000000" "" input  -- call f with empty vase, previous vase state and
                                      -- the input as string of numbers
Laikoni
quelle
Gut gemacht :) ! Was sind die letzten drei "?
Sygmei
@Sygmei es sind zwei Zeichenfolgen f "0000000000" "", zwischen denen braucht man nur keine Leerzeichen. Ich habe dem Code eine Erklärung hinzugefügt.
Laikoni
Schön, jetzt einfacher zu verstehen :)
Sygmei