W tym wyzwaniu Twoim zadaniem jest zbudowanie niekierowanego wykresu z sekwencji dyrektyw. Istnieje jedna dyrektywa dla każdej nieujemnej liczby całkowitej i każda przekształca dany wykres w nowy.
- Dyrektywa
0
: Dodaj nowy odłączony węzeł. - Dyrektywa
1
: Dodaj nowy węzeł i podłącz go do każdego istniejącego węzła. - Dyrektywa
m > 1
: Usuń wszystkie węzły, których stopień (liczba sąsiadów) jest podzielny przezm
. Zauważ, że0
jest podzielna przez wszystkichm
, więc odłączone węzły są zawsze usuwane.
Dyrektywy są stosowane jeden po drugim, od lewej do prawej, zaczynając od pustego wykresu. Na przykład sekwencja [0,1,0,1,0,1,3]
jest przetwarzana w następujący sposób, wyjaśniony przy użyciu niesamowitej grafiki ASCII. Zaczynamy od pustego wykresu i dodajemy pojedynczy wierzchołek zgodnie z instrukcjami 0
:
a
Następnie dodaj kolejny wierzchołek i połącz go z pierwszym, zgodnie z instrukcjami 1
:
a--b
Dodamy kolejny wierzchołek odłączony, a następnie podłączony jeden, zgodnie z zaleceniami 0
i 1
:
a--b c
\ \ /
`--d
Powtarzamy to jeszcze raz, zgodnie z zaleceniami 0
i 1
:
,--f--e
/ /|\
a--b | c
\ \|/
`--d
Na koniec usuwamy wierzchołki stopnia-3 a
i b
zgodnie z instrukcjami 3
:
f--e
|\
| c
|/
d
To jest wykres zdefiniowany przez sekwencję [0,1,0,1,0,1,3]
.
Wejście
Lista nieujemnych liczb całkowitych reprezentujących sekwencję dyrektyw.
Wynik
Liczba węzłów na wykresie określona przez sekwencję.
Przypadki testowe
[] -> 0
[5] -> 0
[0,0,0,11] -> 0
[0,1,0,1,0,1,3] -> 4
[0,0,0,1,1,1] -> 6
[0,0,1,1,0,0,1,1,2,5,7,0,1] -> 6
[0,0,1,1,1,1,5,1,4,3,1,0,0,0,1,2] -> 6
[0,0,1,1,0,0,1,1,5,2,3,0,0,1,1,0,0,1,1,3,4,0,0,1,1,2,1,1] -> 8
[0,0,1,1,0,0,1,1,2,5,7,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,8] -> 14
Szczegółowe zasady
Możesz napisać funkcję lub pełny program. Najkrótsza liczba bajtów wygrywa. Standardowe luki są niedozwolone. Proszę wyjaśnić swój algorytm w swojej odpowiedzi.
Minął tydzień, więc zaakceptowałem najkrótszą odpowiedź. Jeśli później pojawi się jeszcze krótszy, zaktualizuję mój wybór. Wyróżnienie należy do odpowiedzi Petera Taylora , na której oparto kilka innych, w tym zwycięzcę.
źródło
Odpowiedzi:
Pyth ,
3731W tym rozwiązaniu używana jest funkcja zmniejszania (
u
) do tworzenia listy, w której każdy wpis odpowiada węzłowi pozostającemu na liście, a wartość wpisu odpowiada temu, czy węzeł został pierwotnie dodany zgodnie z dyrektywą 0 lub 1.G
jest zmienną akumulatorową w funkcji redukcji i zawiera wyżej wymienioną listę. Jest on inicjowany do pustej listyY
.H
przyjmuje wartość każdego elementuQ
wejściowego, jeden po drugim. Wynik wyrażenia jest przypisywanyG
każdorazowo, a następny wpisQ
jest przypisywanyH
i wyrażenie jest ponownie uruchamiane.Aby
G
poprawnie zaktualizować , istnieją dwie możliwości, jedna dla dyrektywy 0 lub 1 i jedna dla pozostałych dyrektyw. Przypadki te są rozróżniane za pomocą trójskładnika? ... <H2 ...
Jeśli
H
ma wartość 0 lub 1, to wszystko, co musisz zrobić, to DołączH
doG
.+GH
osiąga to.W przeciwnym razie pierwszą rzeczą, którą należy ustalić, jest określenie dla każdego węzła na wykresie liczby sąsiadów. Odbywa się to w dwóch etapach:
Najpierw
s>GT
zlicza liczbę węzłów w węźle wejściowym lub za nim, które wynoszą 1 s. Wszystkie są podłączone do węzła wejściowego, z tym wyjątkiem, że przeliczy się o 1, jeśli węzeł wejściowy to 1.Po drugie, potrzebujemy liczby węzłów wcześniej niż węzeł wejściowy, które są z nim połączone. Jest to 0, jeśli węzeł wejściowy to 0, a indeks węzła wejściowego
T
, jeśli węzeł wejściowy to 1. Ta wartość byłaby podana przez*@GTT
. Nadal istnieje jednak przeliczanie z pierwszej sekcji, które należy poprawić. Dlatego*@GTtT
zamiast tego obliczamy , czyli o 1 mniej, jeśli węzeł wejściowy to 1. Te wartości są sumowane, aby podać liczbę węzłów podłączonych do węzła wejściowego.% ... H
da 0 oznacza, że liczba jest podzielna przezH
, a zatem powinna zostać usunięta, i nie da 0 w przeciwnym razie.f ... UG
da zatem wskaźniki wejściowe, których nie należy usuwać, ponieważf
jest to filtr, a 0 to fałsz.m@Gd
konwertuje te indeksy na 0 i 1 z odpowiednich węzłów.Wreszcie, po znalezieniu wynikowej listy węzłów oznaczonych jako 0 i 1, jej długość jest obliczana (
l
) i drukowana (niejawna).Szeroki pomysł dzięki @PeterTaylor.
źródło
GolfScript (53 bajty)
Demo online
Właściwie to jeszcze nie grałem w golfa, ale odkryłem, że nie jest łatwo wyeliminować zmienne
H
iT
, więc może to być lokalne minimum.Pobiera dane wejściowe na standardowe wejście w formacie
[0 1 2 3]
. Pozostawia wyjście na standardowe wyjście.Nie golfowany:
źródło
CJam,
129 75 73 68 61 4642 bajtówRozwiązanie oparte na algorytmie Petera:
Rozszerzenie kodu do naśladowania.
Poprzednie rozwiązanie (61 bajtów):
Pobiera dane wejściowe ze STDIN, takie jak:
Dane wyjściowe to liczba na STDOUT:
Algorytm :
U
która przechowuje identyfikator węzła, który ma zostać dodany.0
, dodaj[U]
do listy1
, dodajU
do każdej listy na liście i dodaj kolejną listę składającą się z pierwszego elementu każdej listy iU
length - 1
podzielne przezm
i zwracam uwagę na pierwszy element tych list. Po filtrowaniu usuwam cały usunięty identyfikator z pozostałej listy identyfikatorów.Rozszerzenie kodu :
Wypróbuj tutaj
źródło
Pyth
888075 znakówSkończyłem. Może ktoś ma jakieś wskazówki dotyczące gry w golfa.
Y
jest listą przyległości wykresu. Z powodów golfowych trzymam również węzeł na tej liście, nawet po usunięciu węzła (w przeciwnym razie musiałbym zaktualizować wszystkie indeksy). Każdy węzeł ma siebie jako sąsiada. ListaJ
śledzi usunięte węzły.Pokazuję zmiany listy sąsiedztwa na przykładowym wejściu
[0,1,0,1,0,1,3]
:Algorytm jest wtedy dość prosty: Iteruj po wszystkich danych wejściowych, jeśli dane wejściowe == 0: dodaj nowy węzeł ze sobą jako sąsiadem, jeśli dane wejściowe == 1: dodaj nowy węzeł ze wszystkimi węzłami jako sąsiadami (także usuniętymi) i dodaj ten węzeł do listy sąsiadów wszystkich węzłów, jeśli dane wejściowe> 1: określ węzły za pomocą # sąsiada-1% danych wejściowych == 0 i dodaj je
J
, w każdym przypadku, zaktualizuj sąsiadów każdego węzła za pomocąJ
. Na końcu wydrukuj długośćY
minus długość (zestawu)J
.Stosowanie
Wystarczy wywołać skrypt i podać jako dane wejściowe
[0,1,0,1,0,1,3]
lub inny przypadek testowy.źródło
APL,
716555 znaków{⍬≡⍺:≢⍵⋄r←1↓⍺⋄1<c←⊃⍺:r∇i⌿⍵/⍨i←0≠c|+/⍵⋄c:r∇∨⌿↑a(⍉a←⍵,1)⋄r∇0,0⍪⍵}∘(0 0⍴0)
{⍺←0 0⍴0⋄⍬≡⍵:≢⍺⋄(⍺{1<⍵:i⌿⍺/⍨i←×⍵|+/⍺⋄⍵:-⌿↑(1,1⍪⍺)1⋄0,0⍪⍺}⊃⍵)∇1↓⍵}
{g←0 0⍴0⋄(≢g)⊣{1<⍵:g⌿⍨←g/⍨←×⍵|+/g⋄(⊃g)-←g⍪⍨←g,⍨←⍵}¨2,⍵}
Wykres jest reprezentowany jako logiczna macierz przylegania. Wiersze / kolumny są dodawane i usuwane w razie potrzeby.
źródło
Python 2, 296
Każdy węzeł otrzymuje unikalny identyfikator, a identyfikatory sąsiedztwa każdego węzła są rejestrowane. Gdy dyrektywa ma wartość 0, dla nowego węzła dodawana jest pusta lista sąsiadów. Gdy dyrektywa ma wartość 1, identyfikatory wszystkich istniejących węzłów stają się listą sąsiadów dla nowego węzła, a wszystkie inne listy sąsiadów są aktualizowane w celu włączenia nowego identyfikatora węzła. Dla m> 1 węzły z listami sąsiadów, które są wielokrotnością m, są usuwane z listy węzłów i wszystkich list sąsiadów. Dzięki @Optimizer za wykrycie błędu we wcześniejszej wersji.
źródło
NetLogo, 160
Implementacja jest prosta, odczytując każdy symbol i wykonując odpowiednie działanie.
Możesz uruchomić z wiersza poleceń jako
f[0 0 1 1 0 0 1 1 2 5 7 0 1]
.źródło
Ruby
159157( wersja demo )Definiuje funkcję wywoływaną
G
za pomocą składni stabby-lambda. SłużyG[[0, 1]]
do wywoływania go za pomocą poleceń0
i1
.Implementacja jest dość prosta: istnieje
Node
struktura (nazywanaN
powyżej), która zawiera odwołania do wszystkich połączonych węzłów za pośrednictweml
właściwości.G
tworzy potrzebne węzły i manipuluje ich łączami. Wersja do odczytu jest dostępna tutaj .źródło
CJam,
9997 bajtówJest jeszcze wiele do grania w golfa. Algorytm opiera się na śledzeniu macierzy przylegania, ale reprezentowanie pustej macierzy bez konieczności jej specjalnego traktowania powoduje bóle głowy.
Sprawdź to tutaj.
Dane wejściowe to tablica w stylu CJam:
Za pomocą tej uprzęży testowej można uruchomić wszystkie testy:
źródło
Python 2, 174
Prawdopodobnie nadal można dużo grać w golfa.
Użyłem słownika
g
do przedstawienia wykresu. Węzły są oznaczone liczbami i są odwzorowane na zbiór sąsiednich węzłów. Oznacza to, że każda aktualizacja krawędzi musi zostać wykonana w obu punktach końcowych.Świeże indeksy węzłów są tworzone przez zliczanie
n
. Za każdym razem tworzę nowy pusty węzełn
. Na rozkaz0
pozostaje po prostu. Dla polecenia1
jest on połączony ze sobą za pośrednictwem węzłag[i]^={n};g[n]^={i}
; przy użyciu xor uczyń go tak, aby węzeł nie był podłączony do siebie. W przypadku poleceń> 1 jest natychmiast usuwany.Filtrowanie węzłów, których stopień jest wielokrotnością, polega na znalezieniu węzłów, które pozostały (
h
), a następnie umieszczeniuand
go na liście węzłów i sąsiadów każdego węzła.Wreszcie liczba wpisów w słowniku wykresów jest odpowiedzią.
źródło
Mathematica, 223 bajty
Wow, okazało się to dłużej niż się spodziewałem.
Stosowanie:
Oto wyniki z przypadków testowych:
Mniej golfa:
Działa to poprzez przedstawienie wykresu jako listy „list sąsiadów”.
Do dyrektywy 0 po prostu dołączam pustą listę.
Do dyrektywy 1 dołączam listę wszystkich poprzednich węzłów i dodam nowy węzeł do wszystkich poprzednich węzłów.
W przypadku dyrektywy > 1 usunąłem określone węzły i zaktualizowałem resztę.
źródło