Düz bir tahmin oyunu


13

Oynamayı sevdiğim bir oyun var. Sonlu boyutlu bir ızgarada olur (ancak bir küre gibi sarılır). Bu ızgarada rastgele (yalnızca tamsayı) bir nokta seçilir. Sonra, ben, kullanıcı, bir koordinat girişi istenir. Eğer girdim rastgele nokta ile tam olarak eşleşirse, bana kazandığım söylenir. Aksi takdirde, girdim ile rasgele nokta arasındaki noktaya mesafenin söylendiği söylenir. Örneğin, tahmin edersem (2,2)ve rastgele nokta atlasaydı (4,3), o zaman mesafe olurdu sqrt[(3-2)^2 + (4-2)^2] = sqrt[5].

Oyun, oyuncu noktanın doğru yerine gelene kadar devam eder.


Amaç Yukarıda açıklanan oyunun işlevsel bir versiyonunu oluşturun. Bunu yapmak için tam bir program oluşturmanız gerekir. Programınızın yapması gerekenler:

  1. İki giriş isteyin: kartın yüksekliği ve genişliği. Kökeni tahtanın sol üst tarafındadır. Bu girişler aşılmayacaktır 1024.
  2. Bu tahtada rastgele bir nokta seçin; tahmin edilmesi gereken nokta bu olacak.
  3. Bir dönüş simüle eden girişi kabul edin. Giriş, boşlukla ayrılmış bir tamsayı çifti veya iki ayrı tamsayı girişi olacaktır. Bu girdiye yanıt olarak, program iki şeyden birini yapacaktır:
    1. Giriş seçilen rastgele nokta ile eşleşiyorsa, kullanıcının zaferini gösteren bir mesaj gönderin. "Sen kazandın!"
    2. Aksi takdirde, kullanıcının giriş noktası ile rastgele nokta arasındaki mesafeyi girin.
    Her iki durumda da, dönüş sayacını artırmalısınız.
  4. Kullanıcı zafere ulaştığında, kullanıcının aldığı dönüş sayısını gösterin. Ardından program kapanır.

Bonuslar

Bonuslar bu listede göründükleri sırayla uygulanır

  • Programınız D, oyunun gerçekleştiği boyutu tanımlayan bir girdi tamsayısı alırsa -150 bayt . Örneğin, D = 3rasgele bir 3tamsayı noktası oluşturursanız , 3tamsayı girişleri alır ve bu noktalar arasındaki mesafeyi çıkarırsınız .
  • score < 0Kullanıcının daha önce belirtilen boyutlar ve dönüş sayacı üzerinde nerede tahmin ettiğini gösteren bir grafik sunumunu (ASCII veya Resim) sağlarsanız % -50 (veya +% 50 ise ). (İlk bonus için giderseniz, bu bonus sadece 2Dve 1Dmodları için geçerlidir . 3D grafik çıktısı eklerseniz,% -50 ek alırsınız.)
  • -60 bayt sağlayabilirseniz (başlangıçta bir girdi ile seçilir; yani verildiğinde 0normal oyun modunu gerçekleştirin; verildiğinde 1bu oyun modunu gerçekleştirin), noktanın tur başına 1 birim rastgele ortogonal yönde hareket ettiği

Kaydırma hakkında daha fazla bilgi

Sarma yalnızca üçüncü bonusta hareket noktası sınırların herhangi biri boyunca hareket ettiğinde gerçekleşir; bu durumda, hareket noktası ilgili noktaya bükülür, şöyle:

...              ...
..R (move right) R..
...              ...

Bu sarma davranışı, noktanın yön değiştirdiği gerçeğinin yanı sıra, kullanıcının tahminini etkilemez.


Liderler Sıralaması

Bu yazının altındaki Yığın Parçacığı, a) her dil için en kısa çözüm listesi ve b) genel bir lider panosu olarak cevaplardan katalog oluşturur.

Yanıtınızın göründüğünden emin olmak için lütfen aşağıdaki Markdown şablonunu kullanarak yanıtınızı bir başlıkla başlatın:

# Language Name, N bytes

Ngönderiminizin büyüklüğü nerede . Puanınızı artırmak varsa, olabilir onları içinden vurarak, başlığa eski hesapları tutmak. Örneğin:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Başlığınıza birden fazla sayı eklemek istiyorsanız (örneğin, puanınız iki dosyanın toplamı olduğu veya yorumlayıcı bayrak cezalarını ayrı olarak listelemek istediğiniz için), gerçek puanın başlıktaki son sayı olduğundan emin olun :

# Perl, 43 + 2 (-p flag) = 45 bytes

Dil adını, daha sonra snippet'te görünecek bir bağlantı da yapabilirsiniz:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


7
Küçük nitpick: muhtemelen bir küre değil, bir torus gibi sarıldığını söylüyorsunuz. Süreklilik yaratmadan bir 2B ızgarayı bir kürenin üzerine sarmak imkansızdır.
Alistair Buxton

2
Ayrıca tahta sarılırsa, bir kenarı geçerek tahmin ve hedef arasında daha kısa bir yol olabilir.
Alistair Buxton

1
@NBZ Evet, yapabilirsiniz.
Conor O'Brien

1
@NBZ 1 birim tek bir yönde.
Conor O'Brien

2
1. Hala topolojinin ne olduğundan emin değilim. Tahta ise, size daha fazla yardımcı olmak için 10x10rasgele bir nokta, (9,4)ve sanırım (2,2), mesafedir sqrt(13)ya sqrt(53)? (Gelecek için not: garip bir şey yapıyorsanız, rastgele dahil etmeyin, çünkü test senaryoları sağlamayı neredeyse imkansız hale getirir). 2. Üçüncü bonusta, puan hareket etmeden önce veya sonra hesaplanmalı ve çıkarılmalıdır?
Peter Taylor

Yanıtlar:


8

CJam, -113 -139 -152 -157 -159 byte

l~]:B:mr{_ea:i~mr0a*W2mr#+*.+B:,.=_[l~].-:mh_p}g],(

Program 51 bayt uzunluğundadır ve -150 bayt ve -60 bayt bonusları için uygundur.

Oyun modu ve boyut sayısı bir komut satırı argümanı olarak okunur, STDIN'den her boyuttaki boyut. Yana zafer mesajı keyfi , program yazdırır 0.0oyun biter olduğunu belirtmek için (hedefe mesafe).

Test çalıştırmaları

$ cjam game.cjam 0 3; echo
2 2 2
1 1 1
1.4142135623730951
1 1 0
1.7320508075688774
1 0 1
1.0
0 0 1
0.0
4
$ cjam game.cjam 1 3; echo
2 2 2
0 0 0
1.0
0 0 0
0.0
2

Nasıl çalışır

l~]       e# Read a line from STDIN, evaluate it and collect the result.
:B        e# Save the resulting array in B. The result is [B1 ... Bd],
          e# where Bk is the board size in dimension k.
:mr       e# Pseudo-randomly select a non-negative integer below Bk,
          e# for each k between 1 and d.
{         e# Do:
  _       e#   Copy the item on the stack. The original becomes a dummy value
          e#   that will be used to count the number of turns.
  ea      e#   Push the array of command-line arguments.
  :i~     e#   Cast each to integer and dump them on the stack.
          e#   This pushes m (game mode) and d (number of dimensions).
  mr      e#   Pseudo-randomly select a non-negative integer below d.
  0a*     e#   Push an array of that many zeroes.
  W2mr#   e#   Elevate -1 to 0 or 1 (selected pseudo-randomly).
  +       e#   Append the result (1 or -1) to the array of zeroes.
  *       e#   Repeat the array m times.
  .+      e#   Perform vectorized addition to move the point.
  B:,.=   e#   Take the k-th coordinate modulo Bk.
  _[l~]   e#   Push a copy and an evaluated line from STDIN.
  .-:mh   e#   Compute their Euclidean distance.
  _p      e#   Print a copy.
}g        e# While the distance is non-zero, repeat the loop.
],(       e# Get the size of the stack and subtract 1.
          e# This pushes the number of turns.

2
Ve Dennis herkesi geride bıraktı. Tekrar.
Seadrus

1
Skoru yanlışlıkla -152 yerine 152'ye güncelledin ve skor tablosunda sonuncu oldun
Moose

7

Pyth, 91 (-150-60) = -119

VvwaYOvw;JY#IqQ1=dOlY XYd@S[0 @Jd +@Yd?O2_1 1)1)=T[)VYaT^-Nvw2)=ZhZ=b@sT2Iqb0Bb;p"Won in "Z

Eski çözüm: (54-150 = -96)

JYVQaYOvw;#=J[)VYaJ^-Nvw2)=ZhZ=b@sJ2Iqb0Bb;p"Won in "Z

Tüm girdiler yeni bir satırda gerçekleşir.

  • İlk tamsayı oyun modunu temsil eder ( ya 1da0 )
  • Birinci İkinci tamsayı Doyunun boyutlarını temsil eder.
  • Sonraki Dgirişler alan boyutunu temsil eder
  • DBu noktadan sonraki tüm girdiler tahminlerdir

Örnek oynatma (ipuçları gerçek programda görünmez):

  #Hint: Gamemode (1 or 0)
1
  #Hint: Dimensions
3
  #Hint: X-size
4
  #Hint: Y-size
4
  #Hint: Z-size
4
  #Hint: Guesses
  #Hint:[3, 2, 1]
3
2
2
1.0
  #Hint:[3, 2, 1]
3
2
1
1.0
  #Hint:[2, 2, 1]
2
2
1
1.0
  #Hint:[3, 2, 1]
3
2
1
Won in 4

İkinci hamle kazanamaz mı?
JNF

@JNF, oyun modunda 1 hareket edebilir (-60 bayt bonusu)
Jakube

Kutsal moly, bu uzun bir pyth kodu. Gerçekten olsa golfed. Örneğin, kaldırılabilecek iki boşluk görüyorum. Ayrıca: 2 bayt daha kısa olan J=YmOvwvwyerine kullanabilirsiniz VvwaYOvw;JY. Diğer koda bakmadım ama sanırım orada birkaç şeyi kısaltabilirsiniz.
Jakube

@ Jakube, ipucunun bize şu anda noktanın nerede olduğunu söylediğini varsayıyordum
JNF

3

Python 2, 210-150 = 60

from random import*
q,r,o=map,raw_input,int
a=q(randrange,q(o,r().split(' ')))
m=q(o,r().split(' '))
t=1
while m!=a:print sum([(c-d)**2for c,d in zip(m,a)])**.5;m=q(o,r().split(' '));t+=1
print'You won in %d'%t

İlk meydan okuma sadece şimdiye kadar. Çevrimiçi deneyin


3

Pip, 43 42 bayt - 150 = -108

Pano boyutlarını komut satırı bağımsız değişkenleri olarak alır (D, bağımsız değişken sayısından ima edilir). Tahminleri stdin'de boşlukla ayrılmış sayılar olarak alır.

YRR_MgWd:++i&RT$+(y-(q^s))**2Pd"Won in ".i

Bu kod Pip'in dizi programlama özelliklerinden büyük ölçüde yararlanır. Cmdline argümanları dizisi içinde saklanır g. Biz nokta randrange operatörü eşleyerek tahmin edilecek üretmek RRüzerinde gve içine çıkan liste yank ydeğişken. Ardından, koşul aşağıdaki gibi olan ana while döngüsü gelir:

d:++i&RT$+(y-(q^s))**2

  ++i&                  Increment i, the guess counter; the result is always > 0, so the
                          short-circuiting & operator evaluates the next expression:
              q         Read a line from stdin
               ^s       Split on spaces
           y-(   )      Subtract from our chosen point itemwise
          (       )**2  Square, itemwise
        $+              Fold on +, summing the list of squares
      RT                Square root
d:                      Assign this distance to d

Mesafe sıfır değilse, döngünün içi onu yazdırır. Sıfır olsaydı, hedef noktayı vurduk; döngü durur ve program kazanma mesajını ve tur sayısını verir.

Örnek çalışma:

C:\Users\dlosc> pip.py -f guessing.pip 10 5 6 4
5 2 3 2
3.1622776601683795
6 2 3 2
4.123105625617661
3 2 3 2
1.4142135623730951
3 1 3 2
2.23606797749979
3 2 2 2
1.7320508075688772
2 2 3 2
1
2 2 3 1
1.4142135623730951
2 3 3 2
Won in 8

2

R, 134-150 = -16 bayt

function(...){G=sapply(list(...),sample,1)
C=0
repeat{g=scan()
C=C+1
if(any(G!=g))cat(sqrt(sum((G-g)^2)))else{cat("Won in",C);break}}}

2

Haskell, 240-150 = 90

import System.Random
r x=randomRIO(0,x-1)
m=map read.words
g=getLine
main=do g;(fmap m g::IO[Int])>>=mapM r>>=b 1
b c v=do i<-fmap(sqrt.fromIntegral.sum.map(^2).zipWith(-)v.m)g;if i==0 then putStrLn$"Won in "++show c else do print i;b(c+1)v

1

Dyalog APL , 77 71-210 = -139

S F M
P←?S
{P←S|P+(?D)⌽D↑Mׯ1 1[?2]
C+←1
P≢G←⎕:0⊣⎕←.5*⍨+/2*⍨P-G
C}⍣≢C←0

Tamam:

Bunun ⎕IO←0, birçok APL'de varsayılan olan dizin kökeninde 0 ( ) çalıştığını unutmayın .
Boole modunu sağ argüman ( M) ve boyut boyutlarını sol argüman ( S) olarak alır.
Boyut sayısı, çağrıdan önce OP'ye Dgöre ayarlanması gereken (örn D←3.).
P←?Sboyut 1'in her birinde sınırlar olsa da hedef rasgele noktaya ulaşır
{}⍣≢C←0sonuçtan farklı olana kadar işlevi tekrarlayın, Cbaşlangıçta iki sayı listesinden 0
?2rasgele sayı 0 veya 1
¯1 1[]dizinini
kiple çarpın; yapar 0modu ise 0
D↑ile ped 0s boyutların sayısı maç için geçerli hedef ayarlamak dünya boyutu modülüne
(?D)⌽ (boyutlar-1 sayısı ile 0) rastgele döndürmek listesini
P+
S|
P← yeni hedefi noktası tasarrufu
C+←1artım sayaç
P≢G←⎕:giriş tahmin ve ardından hedef noktadan farklı ise ...
P-GHer boyutta mesafeler
2*⍨karesi
+/onlara özetlemek
.5*⍨karekök
⎕←baskı o
0⊣return 0 (ilk değere yani özdeş, yani tekrarla)
C... yoksa, tahmin sayısını döndür (0'dan farklı olarak, döngüyü durdurur ve son değeri döndürür)


@Dennis Aslında, bir işlev yaptığımda kırdım, şimdi tekrar bir program. OP'nin izin verdiği indeks orijini 0'a geçerek "programmite" nin bana mal olduğu kadar çok bayt kazandım.
Adam

1
TAMAM. Merak etme: Bu hangi lehçe? İlk satırın ne yapacağını bilmiyorum ...
Dennis

@Dennis Dyalog. Bu geleneksel bir işlevdir, ilk satır [0] satırıdır, yani işlev başlığıdır, ancak olağandışı görünür çünkü sol arg fn-adı sağ argümanı vardır, ancak sonuç yoktur.
Adam
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.