Losowe rzucanie kostkami

14

W standardowych kościach (kostkach) liczby są ułożone w taki sposób, że przeciwległe twarze dodają siedem. Napisz najkrótszy możliwy program w preferowanym języku, który generuje losowy rzut, po którym następuje 9 losowych napiwków. Przechylenie to ćwierć obrotu kości, np. Jeśli kostka jest skierowana w stronę 5, wszystkie możliwe przechylenia to 1,3,4 i 6.

Przykład pożądanej wydajności:

1532131356

steenslag
źródło

Odpowiedzi:

5

GolfScript, 26 znaków

0{(.6,5@--\-.,rand=).}10*;

Nieco bardziej skompresowana wersja Joeya , w zasadzie obejście problemu z indeksowaniem zera.

Howard
źródło
9

Ruby, 44

c=0;10.times{$><<c=([*1..6]-[c,7-c]).sample}

Znalazłem sztuczkę [* 1..6], przeprowadzając szczęśliwe eksperymenty.

steenslag
źródło
1
Kilka fajnych sztuczek tutaj, świetne rzeczy. Uderzenie się w głowę za brak metody próbkowania Array #.
Lars Haugseth,
4

JavaScript (71 znaków)

Być może trzeba wymienić printz alertlub coś innego, w zależności od środowiska JavaScript.

for(C=L=T=0;C++<10;print(L=T))while(!(T-L&&T+L-7))T=Math.random()*6+1|0
Proszę wstać
źródło
scal pętle, warunkowo zwiększając zewnętrzną, gdy zostanie znaleziona wartość: for (b = n = 10; n; ab && a + b-7 && print (b = a, n -)) a = Math.random () * 6 + 1 | 0
imma
4

GolfScript, 28

0:|;{7,[0|7|-]-.,rand=:|}10*
Joey
źródło
3

Grzmotnąć

#/!bin/bash
f=`expr $RANDOM % 6` 
f=`expr $f + 1`
printf "$f"
for ((i=0; i<9; i++))
do
   ((bad=7-$f))
   next=`expr $RANDOM % 6`
   next=`expr $next + 1`
   while [ $next -eq $bad ] || [ $next -eq $f ]
   do
      next=`expr $RANDOM % 6`
      next=`expr $next + 1`
   done
printf "$next"
f=$next
done

przykładowy kod: http://ideone.com/CCfro

Aman ZeeK Verma
źródło
Użycie ((var=expression))jest bardzo przyjemne - myślałem, że najkrótszą drogą było var=$((expression))Ale dlaczego używasz tego tylko raz i marnujesz mnóstwo znaków na wyrażenie na backty?
Peter Taylor
Nie robię dużo skryptów powłoki, ale z jakiegoś powodu ((var = expr)) w niektórych miejscach zawiodło (tak dziwne: P) Odkąd zacząłem ten skrypt, właśnie jakoś ukończyłem. :)
Aman ZeeK Verma
3

R 56 52

for(i in 0:9)cat(F<-sample(setdiff(1:6,c(F,7-F)),1))
Sven Hohenstein
źródło
@JayCe Świetny pomysł, dziękuję za zwrócenie uwagi!
Sven Hohenstein
Cała
2

Bash z tylko jedną pętlą: 100 99 98 96

dla ((i = 10, f = LOSOWO% 6 + 1; i -;)) zrobić
printf $ f
((n = LOSOWO% 4 + 1, m = f <4? f: 7-f, f = n <m || ++ n <7-m? n: n + 1))
gotowy

http://ideone.com/XrZO7

Kluczową ideą jest to, że aby wybrać losową liczbę w [1, x], która nie jest równa y, możesz wybrać losową liczbę w [1, x-1], a następnie zwiększyć ją, jeśli jest> = y. W tym przypadku chcemy losowej liczby w [1,6], która nie jest równa f lub 7-f. Musimy wykonać dwa testy w kolejności min (f, 7-f), max (f, 7-f).

Zakładając, że początkowo puste środowisko może zapisać 2 znaki, nie inicjując i i zmieniając warunek pętli na i++<10

Peter Taylor
źródło
2

Bash: 97 94 92 90 89 87

Mocno grał w golfa na podstawie odpowiedzi Amana ZeeK Vermy:

dla ((i = 10, f = 0; i -;)) zrobić
dla ((n = f; n == f || n + f == 7; f = RANDOM% 6 + 1)):
gotowy
printf $ f
gotowy

http://ideone.com/QiuTx

NB prawdopodobnie można go zmniejszyć o 5 znaków, zmieniając pierwszą linię na, for((;i++<10;))ale to czyni założenia, które nie zawsze są poprawne. To działa OK w ideone ale ktoś go uruchomić z powłoki mogło ilub feksportowane do czegoś niezerowe.

Peter Taylor
źródło
Chciałbym zrobić wersję bez wewnętrznej pętli, ale obawiam się, że będzie dłużej.
Peter Taylor
To jest niesamowicie niesamowite, chyba jestem zbyt surowy na bash :)
Aman ZeeK Verma
@Aman, większość z nich nie jest specyficzna dla bash. To tylko kilkadziesiąt udoskonaleń z testami po każdym i zmianami, gdy coś zepsułem. Jedynym kawałkiem, który jest naprawdę bashową sztuczką, jest noop, który musiałem sprawdzić. Jeśli jednak masz czas na czytanie man bash, polecam. Kiedyś przeczytałem ją od deski do deski, a samo niejasne wyobrażenie o tym, co jest możliwe i warte sprawdzenia, dobrze mi służyło.
Peter Taylor
2

Windows PowerShell, 45

-join(0..9|%{($d=1..6-ne(7-$d)-ne$d|random)})

Właściwie dość banalne. Generuję listę możliwych rzutów kostkami, 1..6a następnie wybieram tylko te, które nie są równe siedmiu minus ostatni rzut, a następnie tylko te, które nie są równe ostatniemu rzutowi. Z pozostałej listy wybieram następnie losowy element i przypisuję go do $d. Ponieważ $djest początkowo traktowany, 0gdy rzuca normalną kostką za pierwszym razem.

Skrypt testowy:

for($i=0;$i-lt20;$i++){
    $o=@(./tipping.ps1)
    if ($i-gt0-and$o-eq$o2) { throw "Must have random output" }
    if ($o.count-ne1) { throw "Must only have one line of output" }
    if ($o[0]-match'[^1-6]'){ throw "Invalid characters" }
    if($o[0].length-ne10){ throw "Wrong length: $($o[0].length)" }
    $r=[char[]]($o[0])|%{$_-48}
    for ($x=1;$x-lt$r.count;$x++){
        if ($r[$x-1]+$r[$x]-eq7) { throw "Not a tipping: $($r[$x-1]) and $($r[$x])" }
    }
    $o2=$o
}

Historia:

  • 18.02.2011 11:57 (61) Pierwsza próba.
  • 2011-02-18 11:58 (45) Nie muszę generować pierwszej liczby osobno.
Joey
źródło
RozumiemThe term 'random' is not recognized as a cmdlet, function, operable program, or script file. Verify the term and try again.
Peter Taylor,
@Peter: PowerShell v2, proszę. Polecenie Get-Randomcmdlet nie istniało w wersji 1.
Joey
2

jot

Powinno to działać, ale niestety losowy generator J utknął po trzeciej iteracji:

a=:>:i.6
f=:a#~1-(+&(a=])7&-)
((,(?4)&{@f@(_1&{))^:9)>:?6

6 4 5 4 5 4 5 4 5 4

Eelvex
źródło
W żadnym wypadku nie jestem ekspertem od J, ale wydaje mi się, że z tego, co wycierpiałem, skomponowałem odpowiedź J na ten wątek, który (?4)zwykle jest zrolowany raz i traktowany jako stała dla kolejnych iteracji, jeśli nie jesteś ostrożny. Obejrzałem go, używając (?@4:)konstrukcji podobnej do tej.
JB
2

Rubin

66 znaków

(0..9).reduce([]){|m|m<<((1..6).to_a-[d=m[-1]||0,7-d]).shuffle[0]}
Lars Haugseth
źródło
2

J, 30 znaków

>:(?@4:{(i.6)-.],5&-)^:(<10)?6

6 2 3 5 4 2 4 1 3 6

Objaśnienia (czytane od prawej do lewej):

  • ?6 zwraca losową liczbę od 0 do 5
  • ^:(<10)stosuje funkcję 9 razy, kumulując wyniki po drodze. Funkcja to:
  • ?@4:{(i.6)-.],5&-
    • ] , 5&- zwraca tablicę liczby wejściowej i jej uzupełnienie do 5 (obecnie obsługujemy liczby oparte na 0, więc suma przeciwnych ścian wynosi 5)
    • (i. 6) -. usuwa je z pełnego zestawu liczb całkowitych od 0 do 5. Po jednej operacji przechylania od pozycji wejściowej pozostały nam wszystkie prawidłowe pozycje.
    • ?@4: { wybiera jeden z nich losowo.
  • >: zwiększa całą sekwencję, aby sprowadzić liczby z powrotem do przedziału od 1 do 6.
JB
źródło
Miło pomyśleć „>:” na końcu.
Eelvex
1
@Eelvex Nie mam pojęcia, dlaczego prawdziwe kości są od 1 do 6, skoro wszystkie rozsądne rozumowania na ich temat używają od 0 do 5.: D
JB
2

GS2, 16 bajtów

16 2f 25 08 41 20 17 30 16 2f 31 31 25 09 19 32

Oto jak to działa

16 2f 25     # make range from 1 to 6 and push random element
08           # start block
    41       # duplicate top of stack twice
    20 17 30 # negate top of stack and add 7
    16 2f    # push range from 1 to 6
    31 31    # do set-wise difference with each of the two previous numbers
    25       # push a random element from the list
09           # end block
19 32        # repeat block 9 times
rekurencyjny
źródło
Myślę, że gs2 jest nowszy niż to wyzwanie.
lirtosiast
1

QBasic (71 znaków)

Dwie nowe linie są konieczne i zawarte w znaku liczą się jako jeden znak każdy.

RANDOMIZE:FOR I=0TO 9
1N=INT(RND*6)+1:IF L=N OR L+N=7THEN 1
?N:L=N:NEXT
Proszę wstać
źródło
1

TI-BASIC, 38 34

For(I,1,9
Ans→X
Repeat Ans≠X and Ans≠7-X
randInt(1,6
End
Disp Ans
End

Nudne rozwiązanie, ale jest krótsze niż poprzednia wersja. Korzystam z faktu, że na nowym kalkulatorze Ansjest inicjowany do zera.

lirtosiast
źródło
Nie wiem, czy to możliwe, ale dam 50 powtórzeń każdemu, kto znajdzie krótsze rozwiązanie.
lirtosiast
Jak obliczasz 34?
rekurencyjny
Każdy token tutaj ma jeden bajt w pamięci ; TI-BASIC jest standardowo oceniany w ten sposób. Jeśli masz kalkulator, wpisz program, spójrz na ekran zarządzania pamięcią, a następnie odejmij 9 i odejmij długość nazwy programu, aby uzyskać rozmiar kodu.
lirtosiast
1

Java 8, 130 bajtów

v->{int d=(int)(Math.random()*6+1),i=10,p;String r=""+d;for(;i-->0;r+=d)for(p=d;p==d|p+d==7;d=(int)(Math.random()*6+1));return r;}

Wypróbuj tutaj.

Jako pełny program z pełną główną metodą miałby zamiast tego 178 bajtów :

interface M{static void main(String[]a){int d=(int)(Math.random()*6+1),i=10,p;String r=""+d;for(;i-->0;r+=d)for(p=d;p==d|p+d==7;d=(int)(Math.random()*6+1));System.out.print(r);}}

Wypróbuj tutaj.

Pół-port odpowiedzi Bash @AmanZeeKVerma .

Wyjaśnienie:

 v->{              // Method with empty unused parameter and String return-type
   int d=(int)(Math.random()*6+1),
                   //  Random dice-roll 1-6
       i=10,       //  Counter-integer, starting at 10
       p;          //  Temp integer to store new side
   String r=""+d;  //  Result-String, starting at the first dice-roll
   for(;i-->0;     //  Loop (1) 10 times:
       r+=d)       //    After every iteration, append the result with a random side
     for(p=d;      //   Set the new side to the current side
         p==d      //   Loop (2) as long as the new side and current side are the same
         |p+d==7;  //   or as long as both combined are exactly 7:
       d=(int)(Math.random()*6+1)
                   //    Set the new side to a random side 1-6
     );            //   End of loop (2)
                   //  End of loop (1) (implicit / single-line body)
  return r;        //  Return the result-String
}                  // End of method
Kevin Cruijssen
źródło
1

MATLAB 58 bajtów

a=randi(6)
for i=1:9;b=1:6;b([a,7-a])=[];a=b(randi(4))
end
aaaaa mówi o przywróceniu Moniki
źródło
0

> <> , 71 bajtów

Cieszę się, że mogłem zaprezentować xlosowość wskaźnika kodu > <>, ponieważ nie pamiętam, aby go tutaj widziałem.

a&0 v
 /2v
1x3v 
>x< <<
6x4v
 \5v ~
:{:/ ^?=}
:{:/ ^?=7+}
:~$<^&;!?:-1&n

Możesz go wypróbować w tym internetowym tłumaczu (wklej kod, prześlij, uruchom).

Aaron
źródło
Otrzymasz moją opinię, gdy naprawisz rozwiązanie.
lirtosiast
@ThomasKwa Zrobione, być może będę mógł trochę zagrać w golfa, ale przynajmniej jest teraz funkcjonalny.
Aaron,
0

R , 67 bajtów

c(3,5,1,4,2,6)[(sample(1:6,1)+cumsum(sample((-2:2)[-3],9,T)))%%6+1]

Wypróbuj online!

Istnieje odpowiedź golfisty R. Jednak myślę, że jest to inne podejście niż dotychczasowe odpowiedzi.

c(3,5,1,4,2,6)                                                     #A dice and its facets
               (sample(1:6,1)                                      #Initial dice roll
                             +cumsum(sample((-2:2)[-3],9,T)))      #9 tippings in c(-2,-1,1,2)
                                                             %%6+1 #converts to values in [0,6]
              [                                                   ]#
JayCe
źródło
0

05AB1E , 23 bajty

6LΩUTFX?6LʒDXÊsX+7Ê*}ΩU

Zdecydowanie można grać w golfa, ale obecnie go nie widzę ..

Wypróbuj online.

Wyjaśnienie:

6LΩ              # Pick a random value from the range [1,6]
                 #  i.e. [1,2,3,4,5,6] → 3
   U             # Save this random value in variable `X`
TF               # Loop 10 times:
  X?             #  Print `X` without newline to STDOUT
  6Lʒ     }      #  Create a range [1,6] again, and filter it by:
     DXÊ         #   Check if the current value is not equal to `X`
                 #    i.e. 1 and 3 → 1 (truthy)
                 #    i.e. 3 and 3 → 0 (falsey)
     sX+         #   Sum the current value with `X`
                 #    i.e. 1 and 3 → 4
                 #    i.e. 3 and 3 → 6
        7Ê       #   And check if it's not equal to 7
                 #    i.e. 4 and 7 → 1 (truthy)
                 #    i.e. 6 and 7 → 1 (truthy)
     *           #   If both checks are truthy, keep it in the filtered list
                 #    i.e. 1 and 1 → 1 (truthy)
                 #    i.e. 0 and 1 → 0 (falsey)
           Ω     #  Pick a random value from the filtered list
                 #   i.e. [1,2,5,6] → 1
            U    #  And save it in variable `X` for the next iteration of the loop
Kevin Cruijssen
źródło