Utwórz układ słoneczny

39

Wprowadzenie

Jest to oparte na faktycznym problemie, z którym ostatnio miałem do czynienia podczas tworzenia gry komputerowej i pomyślałem, że będzie to dobra runda .

Istnieje siedem głównych klas widmowych gwiazdy, które emitują różne ilości ciepła. Na geologię planet wokół gwiazdy duży wpływ ma ilość ciepła odbieranego z gwiazdy, która jest czynnikiem klasy widmowej i odległości od gwiazdy. Stąd rtęć jest praktycznie stopiona, a Neptun zamrożony.

Galaktyka w mojej grze jest generowana proceduralnie, a losowe wybieranie typów planet dla danych gwiazd okazało się prawdziwym piekłem „jeśli oświadczenie”!

Wyzwanie

Twoja metoda powinna wybrać jedną planetę z listy rodzajów planet odpowiednich dla klasy gwiazdy, na podstawie minimalnego progu ciepła, maksymalnego progu ciepła i liczby losowej. Dla uproszczenia to wyzwanie będzie wykorzystywało tylko gwiazdę klasy G, tak jak nasze słońce.

Wejścia

Liczba całkowita heatz zakresu od 4 do 11 reprezentująca ilość ciepła otrzymanego przez planetę z gwiazdy.

Zmienne

Ta tabela pokazuje możliwe planety na podstawie heat. Twoja metoda powinna najpierw zawęzić dostępne opcje w oparciu o ciepło min i ciepło maks., heatPowinna spaść między nimi. Np. Przy przepływie ciepła 10 jedynymi opcjami byłyby Pustynia, Żelazo i Lawa.

Planet type    Heat min   Heat max   Random Chance
Gas Giant         4          9            15
Ice               4          6            10
Ice Giant         4          6            10
Gaia class        5          7            10
Dense Atmosphere  7          9            10
Desert            7          10           25
Iron              7          10           14
Lava             10          11           6

Następnie prawdopodobieństwo wyboru planety (w pozostałych wyborach) to losowe szanse podzielone przez sumę losowych szans wszystkich wyborów.

W powyższym przykładzie prawdopodobieństwo wyboru żelaza wynosi 14/(25+14+6).

Wydajność

Zwraca typ planety jako ciąg.

Zrób co możesz, aby uniknąć logicznych grotów strzałek. Najkrótszy kod wygrywa, punkty za kreatywność. Miłej gry w golfa!

Absynt
źródło
Czy „klasa” „klasy Gai” powinna być pisana wielkimi literami, jak wszystko inne?
Jonathan Allan
@JonathanAllan jest małą literą, ponieważ nie jest to właściwy rzeczownik
Absynt
1
@Absinthe Dlaczego więc gęstość wielkich liter w gęstej A ?
Erik the Outgolfer
17
... czy ktoś to powiedział? | Witamy w PPCG i miłe pierwsze wyzwanie!
user202729,
3
@EricDuminil znany również jako anty-wzór grotu strzały, znany również jako zagnieżdżone-jeśli-oświadczenie-piekło! wiki.c2.com/?ArrowAntiPattern
Absynt

Odpowiedzi:

12

Galaretka , 78 bajtów

“'ĖøÆḳƙ’ḃ7ṣ6+\+3r/ċ€×“½½½½©ÐÇı‘
“ŀỊẋ8ƒ³ẈRɼƈñqẋẏȧɱḌ<ṄỴḳ⁾ÆʋeẒĊ'@ƬØƓƝ}ḟ¬»ỴW€ẋ"ÇẎX

Łącze monadyczne akceptujące liczbę całkowitą (w [4,11] ), która zwraca listę znaków.

Wypróbuj online!

W jaki sposób?

Tworzy zakresy temperatur planet jako listę list i zlicza występowanie ciepła wejściowego na tych listach, aby uzyskać listę zer i jedynek reprezentujących możliwe typy planet, a następnie mnoży się przez liczby prawdopodobieństwa ośmiu typów planet do uzyskać dystrybucję. Rozkład służy do powtarzania nazw typów planet, a na koniec dokonuje się jednolitego losowego wyboru.

“'ĖøÆḳƙ’ḃ7ṣ6+\+3r/ċ€×“½½½½©ÐÇı‘ - Link 1, getDistribution: integer
“'ĖøÆḳƙ’                        - base 250 integer = 39824688429662
        ḃ7                      - to bijective-base 7 = [1,1,2,4,7,1,4,4,6,2,2,2,2,1,5,3,3]
          ṣ6                    - split at sixes = [[1,1,2,4,7,1,4,4][2,2,2,2,1,5,3,3]]
             \                  - cumulative reduce with:
            +                   -   addition = [[1,1,2,4,7,1,4,4][3,3,4,6,8,6,7,7]]
              +3                - add three = [[4,4,5,7,10,4,7,7],[6,6,7,9,11,9,10,10]]
                 /              - reduce with:
                r               -   inclusive range = [[4,5,6],[4,5,6],[5,6,7],[7,8,9],[10,11],[4,5,6,7,8,9],[7,8,9,10],[7,8,9,10]]
                  ċ€            - count (input) in €ach e.g. for 5: [1, 1, 1, 0,0, 1, 0, 0]
                     “½½½½©ÐÇı‘ - list of code-page indices        [10,10,10,10,6,15,14,25]
                    ×           - multiply                         [10,10,10, 0,0,15, 0, 0]

“ ... »ỴW€ẋ"ÇẎX - Main link: integer
“ ... »         - compressed string = "Ice\nIce Giant\nGaia class\nDense Atmosphere\nLava\nGas Giant\nIron\nDesert"
       Ỵ        - split at new lines = ["Ice","Ice Giant","Gaia class","Dense Atmosphere","Lava","Gas Giant","Iron","Desert"]
        W€      - wrap €ach in a list
            Ç   - call last link (1) as a monad e.g. for 5: [10,10,10,0,0,15,0,0]
           "    - zip with:
          ẋ     -   repeat e.g. for 5:  [["Ice","Ice","Ice","Ice","Ice","Ice","Ice","Ice","Ice","Ice"],["Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant"],["Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class"],["Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant"]]
             Ẏ  - tighten               ["Ice","Ice","Ice","Ice","Ice","Ice","Ice","Ice","Ice","Ice","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant"]
              X - a random choice from that list
Jonathan Allan
źródło
Zwariowany! Dobra robota.
Absynt
@Absinthe Możesz po prostu głosować. Uwaga dodatkowa: W Code Golf zazwyczaj nie przyjmujemy odpowiedzi.
user202729,
2
@ user202729 Dodam głosy za dzień lub dwa. Patrzyłem na stronę GitHub, by zobaczyć Jelly próbującą rozwikłać ten kod. Wierzę Szalony! jest najbardziej odpowiedni :)
Absynt
2
@Absinthe tak, wierzę odcinek opisowe często jest dobrą rzeczą, aby mieć jeszcze zgłoszeń językowych non-ezoterycznych :)
Jonathan Allan
3
Wy, ludzie, jesteście naprawdę szaleni.
Selvek
7

R , 225 223 183 bajtów

Podziękowania dla Giuseppe za sprytne przefakturowanie w celu zmniejszenia go do 188 bajtów; pozostałe pięć zostało ogolonych przy użyciu mniej zbędnych reprezentacji liczb.

i=scan()-4
sample(c("Gas Giant","Ice","Ice Giant","Gaia class","Dense Atmosphere","Desert","Iron","Lava")[l<-c(0,0,0,1,3,3,3,6)<=i&c(5,2,2,3,5,6,6,7)>=i],1,,c(3,2,2,2,2,5,2.8,1.2)[l])

Wypróbuj online!

rturnbull
źródło
To miłe podejście, być może będę musiał pomyśleć o usunięciu mojego labiryntu instrukcji if, jeśli sprzyja temu w C # :)
Absynt
Podejrzewam oszczędność indeks logicznego zamiast używać with, data.framei subsetbędzie krótszy.
Giuseppe
2
188 bajtów
Giuseppe
@Giuseppe, prawdopodobnie możesz zyskać kilka dodatkowych bajtów, używając niektórych moich sztuczek z danymi planet , ale myślę, że poprawię również mój, używając twojego pomysłu oddzielenia wektora prawdopodobieństwa od reszty danych.
Kirill L.
4

JavaScript 212

Edytuj 6 bajtów, oszczędzając dzięki Jonathanowi Allanowi

h=>[963,640,640,649,667,1628,924,437].map((z,i)=>(z/8&7)+4>h|z%8+6<h?0:t=r.push(...Array(z>>6).fill(i)),r=[])&&"Gas Giant,Ice,Ice Giant,Gaia class,Dense Atmosphere,Desert,Iron,Lava".split`,`[r[t*Math.random()|0]]

mniej golfa

h=>( 
   r = [],
   // heat min,max and chance encoded in base 8 with offsets
   // min range 4 to 10, with offset 4, 0 to 6
   // max range 6 to 11, with offset 6, 0 to 5
   [(4-4)*8 + 9-6 + 15*64,
    (4-4)*8 + 6-6 + 10*64,
    (4-4)*8 + 6-6 + 10*64,
    (5-4)*8 + 7-6 + 10*64,
    (7-4)*8 + 9-6 + 10*64,
    (7-4)*8 + 10-6+ 25*64,
    (7-4)*8 + 10-6+ 14*64,
    (10-4)*8+ 11-6+  6*64]
   .forEach( (z,i) => (
      min = (z / 8 & 7) + 4, 
      max = z % 8 + 6,
      chance = z >> 6,
      min > h || max < h 
      ? 0 // out of range
      // add current position i repeated 'chance' times
      // array size in t
      : t = r.push(...Array(chance).fill(i))
   ),
   pos = r[t * Math.random() | 0],
   ["Gas Giant", "Ice", "Ice Giant", "Gaia class", "Dense Atmosphere", "Desert", "Iron", "Lava"][pos]
)

Test

var F=
h=>[963,640,640,649,667,1628,924,437].map((z,i)=>(z/8&7)+4>h|z%8+6<h?0:t=r.push(...Array(z>>6).fill(i)),r=[])&&"Gas Giant,Ice,Ice Giant,Gaia class,Dense Atmosphere,Desert,Iron,Lava".split`,`[r[t*Math.random()|0]]

function test()
{
   var heat=+H.value
   var i,result,hashtable={},rep=1e5
   for (i=0;i<rep;i++)
     result = F(heat),
     hashtable[result] = -~hashtable[result]
 
   console.log('Input',heat)
   for (i in hashtable)
   {
     console.log(i,(hashtable[i]/rep*100).toFixed(2),'%')
   }
}
<input id=H type=number min=1 max =15 value=10>
<button onclick='test()'>Test</button>

edc65
źródło
Kilka twoich 16 podstawowych liczb jest o 1 wyłączone (powinno być [3913, 2630, 2630, 2647, 2681, 6522, 3706, 1707])
Jonathan Allan
Myślę, że (ale nie jestem w 100%) możesz uratować 2, zastępując (z/16&15)je z/16&15. Niezależnie od tego, można zaoszczędzić 6 bajtów przy użyciu kompresji podstawa 8 z przesunięciami trzy i sześć ... użytku [971,648,648,657,675,1636,932,445]z z/8&7+3, z%8+6a z>>6:)
Jonathan Allan
@JonathanAllan offset! Świetny pomysł, dzięki
edc65
@JonathanAllan potrzebuję nawiasów, (z/8&7)+4ponieważ &ma niższy priorytet - byłoby7/8&(7+4)
edc65
1
@Shaggy, czy widziałeś komentarz tuż nad twoim? (krótkie opowiadanie: nie)
edc65
4

Kokos , 214 195 bajtów

t->choice..sum([[n]*g(p)*(g(a)<t<g(b))for*n,a,b,p in'Gas Giant3AF_Ice37A_Ice Giant37A_Gaia class48A_Dense Atmosphere6AA_Desert6BP_Iron6BE_Lava9C6'.split('_')],[])
from random import*
g=int$(?,36)

Wypróbuj online!

Port Pythona miałby 203 200 bajtów długości:

lambda t:choice(sum([[n]*int(p,36)*(int(a)<t<int(b,36))for*n,a,b,p in'Gas Giant3AF_Ice37A_Ice Giant37A_Gaia class48A_Dense Atmosphere6AA_Desert6BP_Iron6BE_Lava9C6'.split('_')],[]))
from random import*

Wypróbuj online!

ovs
źródło
1
Co ciekawe, w chwili pisania tego tekstu Twój port Python pokonuje wszystkie inne rozwiązania Python!
Kirill L.
4

Węgiel drzewny , 115 111 bajtów

≔I⁻N³θF⁸«≔§⪪”↷&∧⬤.YLφκ¦(⁼;σ≕]✂↙ζC” ιη¿›θη¿‹θ§η¹FI✂η²⊞υ黧⪪”↓(″1↨▷]U,&ζ^iI″RSY≡´⍘'#﹪υVw5Vu>D<U5r6⁰Q▷Z◨⌕⁸ΣεCZ”¶‽υ

Wypróbuj online! Link jest do pełnej wersji kodu. Edycja: Zapisano 4 bajty dzięki tylko @ ASCII. Wyjaśnienie:

≔I⁻N³θ

Odejmij 3 od wartości wejściowej, aby można ją było porównać z pojedynczymi cyframi.

F⁸«≔§⪪”↷&∧⬤.YLφκ¦(⁼;σ≕]✂↙ζC” ιη

Podziel ciąg znaków 0715 0410 0410 1510 3710 3825 3814 696na spacje (spacje wydają się lepiej kompresować niż przecinki, ale nie wypróbowałem żadnych innych znaków) i zapętlaj każdą część.

¿›θη¿‹θ§η¹FI✂η²⊞υι»

Porównaj dane wejściowe z pierwszą i drugą cyfrą, a jeśli są między nimi, popchnij indeks pętli określoną liczbę razy do predefiniowanej pustej listy, wypełniając ją.

§⪪”↓(″1↨▷]U,&ζ^iI″RSY≡´⍘'#﹪υVw5Vu>D<U5r6⁰Q▷Z◨⌕⁸ΣεCZ”¶‽υ

Podziel listę planet na nowe linie (znowu z jakiegoś powodu lepiej niż przecinki) i wybierz element odpowiadający indeksowi wybranemu losowo z listy.

Neil
źródło
Niezłe. Jak czynnik Los (u) uwzględnia różne prawdopodobieństwa dla każdej planety? (Nic nie wiem o węglu drzewnym).
Absynt
Wybiera indeks z listy z prawidłowym rozkładem indeksów planetType ze względu na „push indeks pętli określoną liczbę razy do predefiniowanej pustej listy, w ten sposób zapełniając ją”. następnie używając wybranego indeksu, aby uzyskać nazwę planetType.
Jonathan Allan
@JonathanAllan Rozumiem, dziękuję
Absynt
111 bajtów , tak myślę? Zasadniczo po prostu spróbuj użyć znaków wcześniej w klasie znaków, patrz kompresja # 11. Domyślna kolejność zapisuje kolejny bajt, ale w zasadzie tylko wtedy, gdy masz tylko symbole
tylko ASCII
@ Tylko ASCII Wyczyść jak błoto ... dlaczego nowe linie są tam lepsze, ale spacje dla drugiego ciągu?
Neil,
3

R , 196 193 190 175 171 bajtów

sample(readLines(,8),1,,c(3,2,2,2,2,5,2.8,1.2)*((x=scan()-3)>c(0,0,0,1,3,3,3,6)&x<c(7,4,4,5,7,8,8,9)))
Gas Giant
Ice
Ice Giant
Gaia class
Dense Atmosphere
Desert
Iron
Lava

Wypróbuj online!

Początkowo zainspirowany tym rozwiązaniem przez @rturnbull, jednak ponieważ oba zgłoszenia znacznie się zmieniły, obecnie jest to w zasadzie mieszanka pomysłów oryginalnego autora, @Giuseppe, który był bardzo pomocny w komentarzach i moim. Oto podsumowanie kluczowych punktów, które pomogły w zmniejszeniu liczby bajtów:

  • Kodowanie danych planety jako CSV Zbieranie nazw w readLinescelu uniknięcia dużej liczby znaków cudzysłowu wokół ciągów.

  • Poprawianie parametrów cieplnych, abyśmy mogli używać znaków <i >zamiast <=i >=.

  • Zmiana formatu danych ciepła z Heat min, Heat maxna, Heat min, Heat Deltaaby pozbyć się cyfr dwucyfrowych.
    Zastąpiony przez przesunięcie wszystkich liczb o -3

  • Dzieląc wszystkie prawdopodobieństwa planety przez 5, co również skutkuje kilkoma cyframi.

  • Pomnożenie wektora prawdopodobieństw planet przez wektor boolean (wskazujący, czy nasze dane wejściowe spełniają wymagania cieplne), aby zniweczyć prawdopodobieństwa nieodpowiednich planet.

Prawdopodobnie można uzyskać jeszcze kilka bajtów, stosując kompresję danych.
Myślę, że już nie.

Kirill L.
źródło
1
t=zamiast text=zapisuje również 3 bajty.
Giuseppe
1
169 bajtów
Giuseppe
solidna odpowiedź, jednak użycie read.csvpojedynczej kolumny sugeruje readLinescałkowite pozbycie się cytatów, chociaż trzeba jawnie ustawićn
Giuseppe
@Giuseppe, to jednak 171 bajtów, ponieważ usunąłeś również nawiasy, które były niezbędne do zachowania pierwszeństwa operatora, a Twoja wersja daje złe prawdopodobieństwo. Mimo to genialna sugestia!
Kirill L.,
Och, zastanawiałem się, skąd pochodzą te nawiasy ...
Giuseppe
3

Python, 282 bajtów , 261 bajtów:

from random import*
i,p,l=input(),[('Gas Giant',3,11,15),("Ice",3,7,10),("Ice Giant",3,7,10),("Gaia Class",4,8,10),("Dense Atmosphere",6,10,10),("Desert",6,11,25),("Iron",6,11,14),("Lava",9,12,6)],[]
for x in p:exec"l+=x[0],;"*(x[1]<i<x[2])*x[3]
print choice(l)

Całkiem proste - całkiem pewne, że można by bardziej zagrać w golfa - wciąż szukamy lepszego sposobu na przedstawienie zasięgu i prawdopodobieństwa planety. Jeśli i jest w zasięgu typu planety, dołącza ją do listy zgodnie z prawdopodobieństwem, a następnie losowo ją drukuje.

EDYCJA: Podziękowania dla Jonathana Frecha - przerobiłem pętlę for, aby zrzucić kilka bajtów. Lepszy sposób dodawania elementów do listy

Chroman
źródło
3
Witamy w PPCG! Nie jestem pewien, jak policzyłeś bajty, ale otrzymuję tylko 283. Mniej, jeśli to wcięcie jest tabulatorem zamiast 4 bajtów.
Martin Ender
1
Czy nie i in range(x[1], x[2])wyklucza górnej krawędzi ciepła, w przeciwieństwie do specyfikacji?
Graipher
1
270 bajtów .
Jonathan Frech
1
Czy to może pomóc? p,d="Gas Giant,Ice,Ice Giant,Gaia class,Dense Atmosphere,Desert,Iron,Lava".split(","),[ord(i)-10 for i in"#"] d=[[p[x//3]]+d[x:x+3]for x in range(0,len(d),3)]
MustacheMoses
1
@ Chromane Przeprosiny wydaje się, że komentarze usunęły niektóre znaki.
MustacheMoses
2

Oktawa z pakietem statystyk, 178 176 174 158 bajtów

@(h)randsample(strsplit('Gas Giant,Ice,Ice Giant,Gaia class,Dense Atmosphere,Desert,Iron,Lava',','),1,1,('UPPPP_TL'-70).*(h>'IIIJLLLO'-70&h<'PMMNPQQR'-70)){1}

Kod definiuje anonimową funkcję, która wprowadza liczbę i wyprowadza ciąg znaków.

Wypróbuj online!

Wyjaśnienie

Kod

@(h)

definiuje anonimową funkcję z wejściem h.

Ciąg

'Gas Giant,Ice,Ice Giant,Gaia class,Dense Atmosphere,Desert,Iron,Lava'

jest dzielony za pomocą przecinków

strsplit(...,',')

Wynikiem jest tablica komórek ciągów, gdzie każdy ciąg jest klasą planety.

Kod

'IIIJLLLO'-70

definiuje pokazany ciąg i odejmuje 70od punktów kodowych jego znaków. Daje to tablicę minimalnych wartości ciepła minus 1 , to znaczy [3 3 3 4 6 6 6 9],.

Podobnie,

'PMMNPQQR'-70

tworzy tablicę maksymalnych wartości ciepła plus 1 , to znaczy [10 7 7 8 10 11 11 12],.

Porównania

h>...&h<...

podaj tablicę zawierającą truelub falsewskazującą, które klasy planet są możliwe.

Z drugiej strony,

'UPPPP_TL'-70

definiuje tablicę wartości przypadek, [15 10 10 10 10 25 14 6].

Operacja

(...).*(...)

jest zwielokrotnieniem elementarnym dwóch ostatnich tablic ( truei falsezachowują się odpowiednio 0i 1). Daje to tablicę, w której każda klasa planety ma swoją losową szansę lub 0jeśli ta klasa nie jest możliwa na podstawie danych wejściowych. Ta tablica będzie używana jako wagi w losowym próbkowaniu

Wywołanie funkcji

randsample(...,1,1,...)

wybiera jedną z komórek z tablicy komórek ciągów (pierwszy argument wejściowy), używając obliczonej tablicy wag (czwarty argument wejściowy). W szczególności funkcja randsampleautomatycznie normalizuje wagi do prawdopodobieństw, a następnie dokonuje losowego wyboru z tymi prawdopodobieństwami. Wynikiem jest tablica komórek zawierająca ciąg. Kod

{1}

służy do wyodrębnienia tego ciągu, który stanowi wyjście funkcji.

Luis Mendo
źródło
2
Świetne wyjaśnienie, dzięki. Świetny wynik też.
Absynt
2

Python 3 , 263 bajty

from random import*
P=lambda h:"Gas Giant|Ice|Ice Giant|Gaia class|Dense Atmosphere|Desert|Iron|Lava".split("|")[choices(*list(zip(*filter(lambda x:h in range(*x[2:]),zip(*[[int(x,32)for x in"0f4a1a472a473a584a7a5p7b6e7b76ac"][a::4]for a in(0,1,2,3)]))))[:2])[0]]

Wypróbuj online!

MooseOnTheRocks
źródło
1

Perl 5 ( -p), 230 bajtów

@a=(['Gas Giant',4,9,15],[Ice,4,6,10],['Ice Giant',4,6,10],['Gaia class',5,7,10],['Dense Atmosphere',7,9,10],[Desert,7,10,25],[Iron,7,10,14],[Lava,10,11,6]);//;map{push@b,($$_[0])x($$_[3]*($$_[1]<=$'&&$'<=$$_[2]))}@a;$_=$b[rand@b]

Wypróbuj online!

Xcali
źródło
Jeśli usuniesz jeden do minimalnego poziomu ciepła i dodasz jeden do maksymalnego poziomu ciepła (który dałby [Ice,4,5,11]zamiast [Ice,4,6,10], itp.), Będziesz mógł użyć <zamiast <=i >zamiast >=, oszczędzając w ten sposób 2 bajty. (tak, to nie dużo ...)
Dada
1

Nim , 314 298 294 bajtów

import random,sequtils
proc c(h:int)=
 var a= @[""]
 a.del 0
 for n in[("Gas Giant",4,9,15),("Ice",4,6,10),("Ice Giant",4,6,10),("Gaia Class",5,7,10),("Dense Atmosphere",7,9,10),("Desert",7,10,25),("Iron",7,10,14),("Lava",10,11,6)]:(if h>=n[1]and h<=n[2]:a.add repeat(n[0],n[3]))
 echo random a

Dla pętli teraz w jednej linii, bez powrotu, mniej bajtów do typu niejawnego

4 spacje usunięte (dzięki Kevin )

Wypróbuj online!

Panda0nEarth
źródło
Nigdy się nie programowałem Nim, ale myślę, że możesz grać w golfa na czterech polach: w jednym for n in[(; i trzy o if h>=n[1]and h<=n[2].
Kevin Cruijssen
1

05AB1E , 78 76 bajtów

”Œï²°™Ä²° Gaia classêη•™Äµ‰Ÿ± Lava”#8äðýā<•ŒEŽuS,•2ôו9èÁnÇ∞Λ•SÌ2ôεŸIå}ÏSΩè

Wypróbuj online!

Wyjaśnienie

”Œï²°™Ä²° Gaia classêη•™Äµ‰Ÿ± Lava”
popycha sznur Gas Giant Ice Giant Gaia class Dense Atmosphere Ice Desert Iron Lava

#                                          # split on spaces
 8ä                                        # divide into 8 parts
   ðý                                      # join each by spaces
     ā<                                    # push the range [0 ... 7]
       •ŒEŽuS,•                            # push 151010101025146
               2ô                          # split into pieces of 2
                                           # results in [15, 10, 10, 10, 10, 25, 14, 6]
                 ×                         # repeat each number in the range by these amounts
                                           # results in ['000000000000000', '1111111111', '2222222222', '3333333333', '4444444444', '5555555555555555555555555', '66666666666666', '777777']
                  •9èÁnÇ∞Λ•                # push 2724355724585889
                           S               # split to list of digits
                            Ì              # decrement each twice
                                           # results in [4,9,4,6,5,7,7,9,4,6,7,10,7,10,10,11]
                             2ô            # split into pieces of 2
                                           # results in [[4, 9], [4, 6], [5, 7], [7, 9], [4, 6], [7, 10], [7, 10], [10, 11]]
                               εŸIå}       # apply to each pair
                                Ÿ          # range [a ... b]
                                 Iå        # check if input is contained in the range
                                           # ex, for input 10: [0, 0, 0, 0, 0, 1, 1, 1]
                                    Ï      # keep only the indices which are true
                                           # ex, for input 10: ['5555555555555555555555555', '66666666666666', '777777']
                                     S     # split to list of digits
                                      Ω    # pick one at random
                                       è   # index into the list of strings with this
Emigna
źródło
1

Python 3, 199 194 bajtów

from random import*
lambda n:choices("Ice|Ice Giant|Gas Giant|Gaia class|Dense Atmosphere|Desert|Iron|Lava".split('|'),[(0x33b2a53d4a>>5*i&31)*(0xc07878380e3f0707>>8*i+n-4&1)for i in range(8)])

Podział hna osobne maski bitowe i losowe wartości szans (patrz wyjaśnienie) pozwala zaoszczędzić kilka bajtów, eliminując przypisanie hi upraszczając range()rozumienie listy.

Poprzednie rozwiązanie

from random import*
h=0xc033c39e3270a0e51fbc1d40ea
lambda n:choices("Ice|Ice Giant|Gas Giant|Gaia class|Dense Atmosphere|Desert|Iron|Lava".split('|'),[(h>>i&31)*(h>>i+n+1&1)for i in range(0,104,13)])

Definiuje anonimową funkcję, która przyjmuje liczbę całkowitą i zwraca typ planety.

Dla każdego typu planety obliczono wartość 13-bitową. 8 górnych bitów definiuje maskę bitową prawidłowych wartości ciepła dla tego typu planety. Dolne 5 bitów to losowa szansa dla tego typu planety. Na przykład „klasa Gaia” jest poprawnym typem dla wartości ciepła od 4 do 7, więc ma maskę 0b00001111. Ma losową szansę 10 lub 0b01010. Łącząc je, otrzymujemy 13-bitową wartość 0b0000111101010dla typu „klasa Gaia”. 13-bitowe wartości dla każdego typu planety są łączone w celu uzyskania wartości h(najniższe 13 bitów dotyczy typu planety „Lód”). (Nowsza odpowiedź nie łączy tych wartości).

Zrozumienie listy iteruje wartości 13-bitowe, aby utworzyć listę wag, gdzie waga jest przypadkową szansą, jeśli typ planety jest prawidłowym wyborem dla danej wartości ciepła, a zero w przeciwnym razie. Dla każdego typu planety (h>>i&31)wyodrębnia losową szansę dla tego typu planety. (h>>i+n+1&1)ocenia na 1, jeśli typ planety jest prawidłowym wyborem dla wartości ciepła, na w przeciwnym razie ocenia na 0.

Funkcja biblioteczna random.choices(choices, weights)wybiera element z listy opcji na podstawie listy wag.

RootTwo
źródło
i+n+1może być i-~n. TIO
ovs
1

Rubin , 214 193 189 bajtów

->h{'Gas Giant,Desert,Iron,Lava,Ice,Ice Giant,Gaia class,Dense Atmosphere'.split(?,).zip(31006330.digits,75449887.digits,[15,25,14,6]).flat_map{|n,m,x,r|m<h-3&&x>h-3?[n]*(r||10):[]}.sample}

Wypróbuj online!

Asone Tuhid
źródło
Przepraszam, nie otrzymałem danych wyjściowych, czy byłby to pierwszy element na liście?
Absynt
@Absinthe Dodałem kilka nagłówków, sprawdź ponownie. To wszystkie poziomy ciepła od 4 do 11 i losowo generowana planeta dla każdej z nich
Asone Tuhid
Ach, rozumiem dzięki, choć idealnie powinien być tylko jeden ciąg wyjściowy
Absynt
@Absinthe Masz rację, to był tylko mój własny kod testowy, teraz możesz wprowadzić
żądaną
1

Haskell , 377 364 358 318 312 270 265 262 256 251 bajtów

import System.Random
f h|x<-[n|(n,(a,b,c))<-zip(lines"Gas Giant\nIce\nIce Giant\nGaia class\nDense Atmosphere\n
Desert\nIron\nLava")$zip3[4,4,4,5,7,7,7,10][9,6,6,7,9,10,10,11][15,10,10,10,10,25,14,6],h<=
b,h>=a,_<-[1..c]]=(x!!)<$>randomRIO(0,length x-1)

(Dodałem łamanie wierszy, aby wydruk był ładniejszy). Zadaniem mówi „zwrot”, a nie „drukuj”, więc fjest to funkcja, która zwraca losowo wybraną nazwę planety do IOmonady, f :: Int -> IO String.

mainJest main = do {f 10 >>= print}( Haskell wskazówek golfa mówi, że to się nie liczy). Wydruki

"Iron"     -- or "Desert", or "Lava"

(edycje: usunięto &„s przypadek bazowy; przeniósł mainsię; zmieniło się czterokrotnie i unzip, i włączony do strażników wzór i >>=następujące propozycje z Laikoni dzięki !; wdrożone podejście z roztworem Jelly zamiast, powtarzając nazwy; wyraźny typ nie jest już potrzebna ; kolejna rada Laikoni pozwala zaoszczędzić 3 bajty; uczyniła ją IOfunkcją; zaimplementowana rada z pokoju rozmów).

Wypróbuj online!

Will Ness
źródło
Miły! Aby uniknąć zalewania komentarzy, możesz dołączyć do czatu Haskell Of Monads and Men, aby dalej omawiać swoją odpowiedź.
Laikoni
0

Java 8, 398 384 bajtów

n->{String r="",a[];for(String x:"456789~Gas Giant~15;456~Ice~10;456~Ice Giant~10;567~Gaia class~10;789~Dense Atmosphere~10;78910~Desert~25;78910~Iron~14;1011~Lava~6".split(";"))if(x.split("~")[0].contains(n))r+=x+";";long t=0,u=0;for(String x:(a=r.split(";")))t+=new Long(x.split("~")[2]);t*=Math.random();for(String x:a)if((u+=new Long((a=x.split("~"))[2]))>t)return a[1];return"";}

Z pewnością można go jeszcze trochę pograć w golfa, ale prawdopodobieństwo w połączeniu z ciągami nie jest bardzo łatwe w Javie.

Wyjaśnienie:

Wypróbuj online.

n->{                // Method with String as both parameter and return-type
  String r="",      //  Temp-String, starting empty
         a[];       //  Temp String-array
  for(String x:"456789~Gas Giant~15;456~Ice~10;456~Ice Giant~10;567~Gaia class~10;789~Dense Atmosphere~10;78910~Desert~25;78910~Iron~14;1011~Lava~6".split(";"))
                    //  Loop over the String-parts in the format "heats~type~probability"
    if(x.split("~")[0].contains(n))
                    //   If the heats contains the input
      r+=x+";";     //    Append this entire String-part to the temp-String `r`
  long t=0,u=0;     //  Temp numbers, both starting empty
  for(String x:(a=r.split(";")))
                    //  Loop over the temp-String parts:
    t+=new Long(x.split("~")[2]);
                    //   Sum their probabilities
  t*=Math.random(); //  Get a random number in the range [0,sum_of_probabilities)
  for(String x:a)   //  Loop over the temp-String parts again
    if((u+=new Long((a=x.split("~"))[2]))>t)
                    //   The moment the current probability-sum is > the random number
      return a[1];  //    Return the Type of planet
  return"";}        //  Mandatory return we won't encounter (which returns nothing)
Kevin Cruijssen
źródło
0

Min , 280 277 bajtów

:a ' =b (("Gas Giant" 4 9 15) ("Ice" 4 6 10) ("Ice Giant" 4 6 10) ("Gaia Class" 5 7 10) ("Dense Atmosphere" 7 9 10) ("Desert" 7 10 25) ("Iron" 7 10 14) ("Lava" 10 11 6)) (=n (a n 1 get >= a n 2 get <= and) ((n 0 get b append #b) n 3 get times) when) foreach b b size random get

Zaczyna się od ciepła na stosie, pozostawia sznur na stosie. Taki sam ogólny proces jak w przypadku odpowiedzi w języku Python 2.

Wyjaśnienie

Zauważ, że min jest konkatenatywny

:a ' =b                               ;Set the value on the stack (heat) to a, set empty quot to b
(("Gas Giant" 4 9 15) ("Ice" 4 6 10) ("Ice Giant" 4 6 10) ("Gaia Class" 5 7 10) ("Dense Atmosphere" 7 9 10) ("Desert" 7 10 25) ("Iron" 7 10 14) ("Lava" 10 11 6)) ;Data to be iterated over
(=n                                   ;  set n to current item
 (a n 1 get >= a n 2 get <= and)      ;    check if n is between the min (2nd elment of n) and max (3rd element of n) heat
 (
  (n 0 get b append #b) n 3 get times ;      insert the name(1st element of n) into the quot of names (b) a number of times corresponding to the 4th element of n
 ) when                               ;    when the previous check is true
) foreach                             ;  for every quot in previous data
b b size random get                   ;choose a random element from the list of names
Panda0nEarth
źródło
0

PowerShell, 56 + 135 (plik CSV) + 1 (nazwa pliku) = 192 bajty

param($z)ipcsv a|?{$z-in$_.m..$_.x}|%{,$_.p*$_.r}|Random

Wypróbuj online! (jest to nieco zmodyfikowana wersja, która tworzy tymczasowy plik CSV opisany poniżej)

Importuje plik CSV za pomocą ipcsv(skrót od Import-CSV) o nazwie aw katalogu lokalnym, który zawiera:

P,m,x,r
Gas Giant,4,9,15
Ice,4,6,10
Ice Giant,4,6,10
Gaia class,5,7,10
Dense Atmosphere,7,9,10
Desert,7,10,25
Iron,7,10,14
Lava,10,11,6

To automatycznie tworzy iterowalną tablicę skrótów takich rzeczy jak:

@{P=Gas Giant; m=4; x=9; r=15}
@{P=Ice; m=4; x=6; r=10}
...

Następnie używamy Where-Object( ?), aby wyciągnąć te wpisy, w których naszą wejściową liczbą całkowitą $zjest -inzakres $_.mdo $_.x(tzn., Że jest w zakresie ciepła). Następnie pompujemy je do Foreach-Objectpętli ( %), która tworzy tablicę ciągów nazw na podstawie losowej szansy tych nazw. Na przykład utworzy to tablicę 15 "Gas Giant"ciągów, jeśli to ciepło się zgadza. Następnie wkładamy te, w Get-Randomktóre wyciągną odpowiedni sznurek o odpowiedniej wadze.

AdmBorkBork
źródło
-1

PHP , 1236 bajtów

<?php
$heat = (int)fgets(STDIN);
$planets =
    [
        'Gas Giant' =>        ['heat_min' => 4, 'heat_max' => 9, 'selection_chance' => 15],
        'Ice' =>              ['heat_min' => 4, 'heat_max' => 6, 'selection_chance' => 10],
        'Ice Giant' =>        ['heat_min' => 4, 'heat_max' => 6, 'selection_chance' => 10],
        'Gaia class' =>       ['heat_min' => 5, 'heat_max' => 7, 'selection_chance' => 10],
        'Dense Atmosphere' => ['heat_min' => 7, 'heat_max' => 9, 'selection_chance' => 10],
        'Desert' =>           ['heat_min' => 7, 'heat_max' => 10, 'selection_chance' => 25],
        'Iron' =>             ['heat_min' => 7, 'heat_max' => 10, 'selection_chance' => 14],
        'Lava' =>             ['heat_min' => 10, 'heat_max' => 11, 'selection_chance' => 6],
    ];
foreach ($planets as $planet) {
    $chance_sum += ($heat >= $planet['heat_min'] && $heat <= $planet['heat_max']) * $planet['selection_chance'];
}
while (true) {
    foreach ($planets as $name => $planet) {
        $prob = 100 * ($heat >= $planet['heat_min'] && $heat <= $planet['heat_max']) * $planet['selection_chance'] / $chance_sum;
        if (rand(0, 100) < $prob) {
            echo $name."\n";
            exit;
        }
    }
}
?>

Wypróbuj online!

Agnius Vasiliauskas
źródło
5
Odpowiedzi na pytania związane z golfem muszą pokazać wysiłek w golfa. Możesz to zrobić o wiele krócej, usuwając białe spacje . Następnym krokiem byłoby skrócenie nazw zmiennych do nazw pojedynczych znaków.
ovs