Zagraj w anagram na dobre!

12

Zadanie

W tym wyzwaniu Twoim zadaniem jest napisanie kodu, który generuje losowo jeden z wybranych anagramów z równomiernym rozkładem, ale nigdy nie powinien wypisywać się sam.


Opracowanie

Bez danych wejściowych program powinien wypisać dowolny z anagramów kodu źródłowego. Twój program nigdy nie powinien wyświetlać własnego źródła takim, jakim jest, tzn. Nigdy nie powinno być quine.


Wejście

Twój program nie może przyjmować żadnych danych wejściowych. Jeśli jednak Twój język wymaga wprowadzania danych jako konieczności, możesz założyć, że będzie on pisany małymi literami a. Nie wolno jednak używać danych wejściowych w jakikolwiek sposób.


Wynik

Twój program może generować dane w dowolny sposób, z wyjątkiem zapisu w zmiennej. Zapis do pliku, konsoli, ekranu itp. Jest dozwolony. Funkcja returnjest również dozwolona.


Dodatkowe zasady

  • Kod źródłowy twojego programu musi mieć co najmniej 3 znaki (nie 3 bajty).

  • Kod źródłowy twojego programu musi mieć co najmniej 3 możliwe anagramy (z wyłączeniem siebie). Na przykład aabnie liczy się jako prawidłowe zgłoszenie, ponieważ aabma tylko dwa anagramy inne niż aab( baai aba).

  • Twój program nie może generować błędów.

  • Twój program powinien wypisywać dokładnie swoje anagramy .

  • Obowiązują standardowe luki i standardowe zasady quine .


Przykład

Załóżmy, że kod źródłowy twojego programu to abc. Powinien losowo generować dowolne z poniższych (z równomiernym rozkładem):

  1. acb
  2. bca
  3. bac
  4. cba
  5. cab

I nigdy nie powinien generować abc.


Zwycięskie kryterium

To jest , więc wygrywa najkrótszy kod w bajtach! W przypadku remisu wcześniej opublikowane rozwiązanie wygrywa!

Arjun
źródło
Związane .
Arjun
Czy musi zagwarantować, że zachowuje się poprawnie, czy tylko z prawdopodobieństwem 1?
PyRulez
@PyRulez W tym wyzwaniu Twoim zadaniem jest napisanie kodu, który generuje losowo jeden z anagramów wybranych losowo z równomiernym rozkładem ... (Pierwsze zdanie (poniżej Zadania ))
Arjun
@Arjun, więc czy 0% szansy na niepowodzenie jest w porządku?
PyRulez
@PyRulez Failure? Kod ma wypisywać jeden ze swoich anagramów (z wyjątkiem siebie) wybranych losowo, z równymi szansami na wydrukowanie dowolnego anagramu. Nie wiem, co masz na myśli przez „Failure”.
Arjun

Odpowiedzi:

5

Galaretka , 15 bajtów

“v0¡µṾ;ḢŒ!QḊX”v

Po prostu na początek; jest to prawie na pewno do pokonania. Jest to w zasadzie połączenie uniwersalnego konstruktora quine i funkcji „wybierz losową permutację inną niż wejściowa”; ten drugi może być ulepszony, pierwszy prawie na pewno.

Wyjaśnienie

Uniwersalny konstruktor quine

“v0¡µṾ;Ḣ”v
“       ”v   Evaluate the following, given {itself} as argument:
 v0¡µ          No-op (which starts with "v")
     Ṿ         Escape string
      ;Ḣ       Append first character of {the argument}

Może to być postrzegane jako quine, jeśli jest uruchamiane samo. Jest to również właściwy quine według większości znanych mi definicji; nie odczytuje własnego źródła (raczej zawiera literał, który jest „ewaluowany” i otrzymuje kopię siebie jako argumentu), może przenosić ładunek (jak pokazano tutaj!), a vpoza nim ciąg dosłowność jest zakodowana przez vwnętrze.

Wybierz losowy anagram

Œ!QḊX
Œ!     All permutations
  Q    Discard duplicates
   Ḋ   Discard the first (i.e. the string itself)
    X  Choose random element

To jest naprawdę nieskuteczne na tak długim ciągu, więc nie byłem w stanie przetestować programu jako całości, ale przetestowałem go na krótszych ciągach i wydaje się, że działa poprawnie.


źródło
Dlaczego Thins nie działa w TIO?
Pan Xcoder
@ Mr.Xcoder Prawdopodobnie omija limit 60 lat.
Erik the Outgolfer
Och, tak, masz rację.
Pan Xcoder,
Podczas gdy masz go w liczbie bajtów, Twój kod pomija to, co konieczne Q. Jednak myślę, że można zmienić to „wszystkie permutacje” metody z pomocą „Shuffle” jeden z zastosowaniem Ẋ⁼¿, oszczędzając bajt jednocześnie pozwalając go do pracy na TIO.
Jonathan Allan
4

CJam , 17 bajtów

{`"_~"+m!(a-mR}_~

To się wkrótce nie skończy, więc tym razem nie ma łącza do TIO.

Na pocieszenie oto 20-bajtowe rozwiązanie, które kończy się bardzo szybko:

{`"_~"+:S{mr_S=}h}_~

Wypróbuj online!

Wyjaśnienie

{`"_~"+   e# Standard quine framework, leaves a string equal to the source
          e# code on the stack.
  m!      e# Get all permutations. The first one will always be the original order.
  (a      e# Remove that copy of the source code and wrap it in a new list.
  -       e# Remove all copies of the source code from the list of permutations.
  mR      e# Pick a random permutation.
}_~

Zamiast tego 20 bajtowe rozwiązanie tasuje kod źródłowy, aż różni się od oryginału.

Martin Ender
źródło
4

Python 2, 117 bajtów

Nieoczekiwanie to rozwiązanie jest krótsze niż się spodziewałem. Tasuje kod źródłowy, aż różni się od oryginału.

-2 bajty, dzięki @ mbomb007-3
bajty, dzięki @Wondercricket

Wypróbuj online

s=r"""from random import*;R='s=r\"""'+s+'\"""'+';exec s';L=R
while L==R:L=''.join(sample(R,len(R)))
print L""";exec s

Jest to jedna z podstawowych quin w Pythonie, którą zmodyfikowałem

s = r"print 's = r\"' + s + '\"' + '\nexec(s)'"
exec(s)

Generowanie anagramu odbywa się za pomocą losowego modułu

L=R
while L==R:L=''.join(sample(L,len(L)))

Gdzie R zawiera kod źródłowy

s=...
R='s=r\"""'+s+'\"""'+'\nexec s'

Potrzeba było potrójnych cudzysłowów, ponieważ byłem zmuszony utrzymywać separatory linii w kodzie. Anagramy i tak będą miały 3 linie.

Dead Possum
źródło
1
exec szamiastexec(s)
mbomb007
Ponieważ strjest niezmienne, można zaoszczędzić bajtów wykonując L=Ri korzystania samplena Lzamiast używać shufflena list. repl.it . Pomysł pochodzi z tego Stackoverflow
Wondercricket
@Wondercricket Sample zwraca listę znaków, więc porównanie jej wyników z R zawsze zwraca False. Ale zmiana układu pomaga, dziękuję za pomysł!
Dead Possum
3

Java 7, 376 428 426 428 bajtów

import java.util.*;class M{public static void main(String[]a){String s="import java.util.*;class M{public static void main(String[]a){String s=%c%s%1$c,x=s=s.format(s,34,s);for(List l=Arrays.asList(x.split(%1$c%1$c));x.equals(s);s=s.join(%1$c%1$c,l))Collections.shuffle(l);System.out.print(s);}}",x=s=s.format(s,34,s);for(List l=Arrays.asList(x.split(""));x.equals(s);s=s.join("",l))Collections.shuffle(l);System.out.print(s);}}

+52 i +2 bajty dla dwóch poprawek błędów. Nie sprawdzałem (poprawnie), czy Losowo generowany Ciąg był równy oryginalnemu kodowi źródłowemu. Szanse na to są astronomiczne, biorąc pod uwagę liczbę zaangażowanych postaci, ale muszę to zweryfikować niezależnie od zgodności z regułami wyzwań.

Mój pierwszy odpowiedź w Javie ..
Spróbuj tutaj.

Możesz usunąć oba Collections.shuffle(l)i dodać !przed nimi, x.equals(s)aby sprawdzić, czy dane wyjściowe rzeczywiście odpowiadają programowi:
Wypróbuj tutaj.

Wyjaśnienie:

  • String sZawiera kod źródłowy niesformatowany.
  • %ssłuży do wprowadzania tego ciągu do siebie za pomocą s.format(...).
  • %c, %1$ci 34służą do formatowania podwójnych cudzysłowów.
  • s.format(s,34,s) łączy to wszystko razem

Ta część kodu odpowiada za generowanie losowego anagramu:

// Strings `s` and `x` now both contain the source-code:
x=s=s.format(s,34,s);

// Create a list with the characters of this source-code-String and loop
for(List l=Arrays.asList(x.split(""));
    // as long as String `x` equals String `s`
    x.equals(s);
    // Shuffle the list, and set it to `s` in every iteration of the loop:
    s=s.join("",l))Collections.shuffle(l);
// End of loop (implicit / single-line body)

// And then print the random anagram to STDOUT:
System.out.print(x);
Kevin Cruijssen
źródło
1

05AB1E , 22 bajty

"34çìDJœ¦.R"34çìDJœ¦.R

To tworzy listę, która jest zbyt duża dla TIO, więc link używa mniejszego ciągu, ale pomysł jest taki sam.

Wypróbuj online!

"34çìDJœ¦.R"           # Push this string
            34ç        # Push "
               ì       # Prepend
                DJ     # Duplicate and join 
                  œ¦   # Push all permutations except the original
                    .R # Pick a random element
Riley
źródło
1

JavaScript (ES6), 128 bajtów

!function a(){b="!"+a+"()",c=b.split(""),c.sort(()=>Math.round(Math.random())-.5),c!=b.split("")?console.log(c.join("")):a()}();

Używa sort () zwracającego losowo -1,0 lub 1 do losowego przetwarzania danych wyjściowych.

Tim
źródło
0

Bash, 27 96 bajtów

i=`cat $0`&&e=`fold -w1 $0|shuf|tr -d '\n'`&&while [ "$e" = "$i" ]; do `$0`; exit; done&&echo $e

folddzieli kod na linie, shuftasuje linie i trskłada kod z powrotem

naprawiono problem z wyjściem samego siebie, teraz nigdy się nie wyprowadza

Wypróbuj online!

DrnglVrgs
źródło
1
Czy ma szansę wygenerować sam kod bez zmian?
Dead Possum
Wydaje się również, że tasuje tylko linie, więc nie wszystkie permutacje są możliwe, w szczególności, ponieważ program ma tylko jedną linię ...
Martin Ender
Wszystkie permutacje są możliwe, przetestuj to. Naprawiam problem, może sam się
wypowiada
1
To $0wygląda na naruszenie „Twój program nie może przyjmować żadnych danych”.
manatwork
Jestem prawie pewien, że to tylko nazwa pliku. Dlatego nawet jeśli nie został wprowadzony, jest to oszustwo::
CalculatorFeline