Liczba trójkątów

11

Kredyt

Moje podziękowania dla listowego pytania Rand Al'Thora za inspirację do tego wyzwania golfowego.

tło

Charakter tego wyzwania opiera się na algorytmie wspomnianym przez Rand w jego „A Triangle Formed of Three Letters”:

  • Zacznij od ciągu 10 liter, z których każda to X, Y lub Z.
  • Pod każdym rzędem utwórz następny rząd w następujący sposób. Jeśli dwie sąsiednie litery są takie same, napisz pod nimi tę samą literę; jeśli się różnią, napisz pod nimi trzeci list.

Powtórzyłbyś wtedy poprzedni krok, aż będziesz miał jedną literę w dziesiątym rzędzie.

Wyzwanie

Zamierzamy obrócić matematycznie powyższy algorytm:

  • Zacznijmy od sekwencji 10 cyfr, każda oddzielona spacją, z których każda ma 1, 2 lub 3.
  • Pod każdym rzędem utwórz następny rząd w następujący sposób. Jeśli dwie sąsiednie cyfry są takie same, napisz pod nimi tę samą cyfrę; jeśli są różne, wpisz trzecią cyfrę pod nimi.
  • Powtarzaj poprzedni krok, aż uzyskasz jeden końcowy numer.

Tak więc, postępując zgodnie z tym algorytmem, jeśli 1 2 3 3 1 3 1 3 1 2na przykład zaczynasz od wiersza , generowany jest następujący trójkąt:

Input: 1 2 3 3 1 3 1 3 1 2

Output:

1 2 3 3 1 3 1 3 1 2
 3 1 3 2 2 2 2 2 3 
  2 2 1 2 2 2 2 1  
   2 3 3 2 2 2 3   
    1 3 1 2 2 1    
     2 2 3 2 3     
      2 1 1 1      
       3 1 1       
        2 1        
         3         

Jestem również ciekawy, jaka jest suma wszystkich cyfr w trójkącie liczbowym, więc dodaj wszystkie te cyfry i umieść tę sumę w jedenastym rzędzie, z wyrównaniem do prawej do ostatniej cyfry w pierwszym rzędzie. Nasz trójkąt liczbowy będzie więc wyglądał następująco (spacje w moim przykładzie są reprezentowane poniżej przez .znak, aby pokazać formatowanie).

Input: 1 2 3 3 1 3 1 3 1 2

Output:

1.2.3.3.1.3.1.3.1.2
.3.1.3.2.2.2.2.2.3.
..2.2.1.2.2.2.2.1..
...2.3.3.2.2.2.3...
....1.3.1.2.2.1....
.....2.2.3.2.3.....
......2.1.1.1......
.......3.1.1.......
........2.1........
.........3.........
................109

Twoim wyzwaniem jest napisanie kodu, który może zaczynać się od wprowadzonego ciągu / tablicy / etc. z dziesięciu cyfr, jak w moim przykładzie, a następnie zastosuj algorytm, aby wygenerować dziesięć wierszy, które utworzą trójkąt liczbowy, a następnie jedenasty wiersz, który wyświetli sumę wszystkich cyfr z wyrównaniem do prawej.

Testowanie

Testowanie tego ciągu można wykonać przy użyciu losowo wygenerowanego ciągu dziesięciu wybranych przez Ciebie cyfr lub wygenerowanego z fragmentu poniżej ...

c1=()=>('1331123221'+(Math.random()*(1<<24)|0).toString(4)).replace(/0/g, "").slice(-10).split("").join(" ");

$("#btn").click(function(){
  $("#str").val(c1());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="str"><button id="btn">Get numbers</button>
<br>
Please use this snippet to generate a starting row for testing your code. Alternatively, you can also use a string of your choice, so long as it's ten digits (ranging from 1 to 3), separated by single spaces.

Zasady

  1. Obowiązują zasady gry w golfa, więc najmniejsza liczba bajtów wygrywa wyzwanie. W przypadku dwóch zgłoszeń o tym samym niskim wyniku, zwycięzca zostanie nagrodzony na podstawie liczby głosów oddanych.
  2. To, czego właściwie oczekujemy, to 11 wierszy o długości 19 znaków ... Sposób renderowania ostatecznego wyniku zależy wyłącznie od Ciebie: macierz, konsola, wyjście pliku, STDOUT itp., Więc użyj dowolnej metody wyjściowej, która Ci się podoba pracuj na swoją korzyść. Jedyną regułą w wynikach jest to, że mamy 11 wierszy z 19 znakami w każdym wierszu w formacie podobnym do powyższego ...
  3. Jeśli to pomaga Twojemu kodowi, użyj dowolnego separatora cyfr ... Pamiętaj tylko, że czytelność może być czynnikiem przyczyniającym się.
  4. Żadnych głupich luk .
  5. Zakodowane na stałe wejście nie jest dozwolone. Celem tego kodu jest to, że można go używać do uzyskiwania różnych wyników za każdym razem przy różnych danych wejściowych. 1 1 1 1 1 1 1 1 1 1Na przykład kodowanie całkowicie neguje cały sens algorytmu.

Zobacz, co wszyscy wymyślą!

WallyWest
źródło
1
Czy potrzebuję separatora, jeśli mój trójkąt jest wyrównany do środka (co jest dzięki temu czytelne)?
JungHwan Min
1
Wygląda to tak bez spacji (moja odpowiedź ma spację, która zajmuje 10 bajtów).
JungHwan Min
2
Udzielone pozwolenie
WallyWest,
1
Zauważ, że dla ciągu 10 (lub dowolnej liczby 1 większej niż potęga 3) cyfr, ostatnia cyfra jest trywialnie obliczana z pierwszej i ostatniej cyfry w ciągu; pozostałe cyfry nie mają znaczenia.
Neil

Odpowiedzi:

1

05AB1E , 32 26 bajtów

DvÐOˆðýðN×.ø,ü+3%3^}\¯O19j

Wyjaśnienie

D                 # duplicate input
v                 # for y,N in input,len(input): (10 times do)
 Ð                # triplicate current list
 Oˆ               # sum one copy and add it to global array
 ðý               # merge one copy on spaces
   ðN×.ø          # surround it with N spaces
        ,         # and print it
 ü+               # reduce one copy by addition
   3%             # modulus 3
     3^           # XOR 3
                  # this is the list sent to the next iteration
}                 # end loop
\                 # drop empty list left over from last iteration of loop
 ¯O               # sum the global array giving the triangles total sum
   19j            # join with spaces up to 19 chars

Wypróbuj online!

Emigna
źródło
7

Mathematica, 104 97 90 94 bajtów

{Grid[List@*Row/@#],#~Total~2}~Column~Right&[NestList[3-Mod[+##,3]&@@@Partition[#,2,1]&,#,9]]&

Wyjaśnienie

Partition[#,2,1]

Dzieli dane wejściowe na długość 2, offset 1 partycje.

3-Mod[+##,3]&@@@

Pobiera każdą partycję i oblicza odpowiednie dane wyjściowe.

W grę wchodzi sztuczka. Dodałem dwie liczby, wziąłem mod 3 i odjąłem ten wynik od 3. To daje pożądaną liczbę. (np. 3 - ((2 + 1) mod 3) = 3)

NestList[ ... ,9]

Powtarza powyższy proces dziewięć razy, podając wszystkie iteracje jako wynik.

Grid[List@*Row/@#]

Sformatuj każdą iterację w wierszach i umieść całą rzecz w jednej kolumnie (wyrównanie do środka), tworząc trójkąt.

#~Total~2

Weź sumę wszystkich liczb.

{...}~Column~Right

Połącz trójkąt z sumą i wyrównaj do prawej całość (trójkąt jest już wyrównany, więc jego wyrównanie nie zostanie zmienione).

JungHwan Min
źródło
1
Inspirowane podejście z jedną funkcją, która obsługuje zarówno identyczne, jak i różne typy rodziców ... Podoba mi się!
WallyWest,
3

JavaScript (ES6), 143 142 bajty

Zapisano 1 bajt dzięki @Neil

a=>a.map((_,i)=>(q=" ".repeat(i))+(a=a.map(c=>(x+=r=i&&p^(p=c)||c,r),p=i&&a.shift())).join` `+q,x=0).join`
`+`
`+(" ".repeat(18)+x).slice(-19)

Próbowałem łączyć różne części, ale skończyło się to 5 bajtami dłużej:

a=>[...a.map((_,i)=>(a=a.map(c=>(x+=r=i&&p^(p=c)||c,r),p=i&&a.shift())).join` `+" ".repeat(i),x=0),x].map(q=>(" ".repeat(18)+q).slice(-19)).join`
`
ETHprodukcje
źródło
Świetna robota! Czy sztuczka JHM może 3-((x+y)%3)pomóc w zmniejszeniu tego kodu?
WallyWest,
2
Nie. p^c||pjest już nieco krótszy :-)
ETHproductions
Jak, do diabła, tęskniłem za tym? Oczywiście! Funkcje XOR działają tutaj dobrze!
WallyWest,
1
XOR ?! Nie mogłem o tym myśleć. To powiedziawszy, niestety, użycie XOR powoduje, że mój kod jest dłuższy: P
JungHwan Min
Do i?p^(p=c)||p:cczego możesz użyć i&&p^(p=c)||c?
Neil
2

Rubin, 134 101 bajtów

Korzystanie z sztuczki modulo JHM.

->a{b=*a
(0..8).map{|i|[" "*i,a=a.each_cons(2).map{|x,y|b<<n=3-(x+y)%3
n}]*" "}<<"%19d"%b.reduce(:+)}

Zobacz na eval.in: https://eval.in/649993

Jordania
źródło
2

CJam ,  44  40 bajtów

l~{S*\_S*\2ew{:+3%3^}%2$N@}A%_s:~:+sJSe[

Wypróbuj online!

Wyjaśnienie

l~       e# Read and evaluate input.
{        e# Map this block over i in the range [0 1 ... 9].
  S*     e#   Get a string of i spaces (the indentation).
  \_     e#   Swap with the current line of trits and duplicate it.
  S*     e#   Join the trits with spaces.
  \2ew   e#   Swap with the other copy of the trits and get all consecutive pairs.
  {      e#   Map this block over the pairs...
    :+   e#     Sum the pair.
    3%   e#     Modulo 3.
    3^   e#     XOR 3.
         e#     This expression (x+y)%3 ^ 3 computes the required mapping.
  }%     e#   Now this is the next line.
  2$     e#   Copy the indentation (to pad the lines to equal length).
  N      e#   Push a linefeed.
  @      e#   Pull up the next line.
}A%      e# The result of this is a nested array whose string representation is
         e# the required triangle.
_s       e# Duplicate and flatten into a string.
:~       e# Eval each character which gives a list of all the trits.
:+       e# Sum that.
s        e# Turn the sum into a string.
JSe[     e# Left-pad it with spaces to width 19.
Martin Ender
źródło
Jak zawsze bardzo imponujące! Jak dotąd przewodzisz!
WallyWest,
1
@WallyWest Thanks. :) Poczekaj tylko Pyth, Jelly i MATL. ;)
Martin Ender
Właściwie jestem ciekawy, jak będzie wyglądać rozwiązanie GolfScript ...;)
WallyWest,
Och, ktoś ma zamiar opublikować rozwiązanie SQL? ;)
WallyWest,
1

Python 2, 164 bajty

Stosunkowo proste iteracyjne rozwiązanie.

L=input()
s=0
for i in range(len(L)):
    print" "*-~i+" ".join(`L`[1::3]);s+=sum(L);N=L;L=[]
    for a,b in zip(N,N[1:]):L+=[list({1,2,3}-{a,b}),[a]][a==b]
print"%19s"%s

Wypróbuj online

mbomb007
źródło
1

PHP, 143 bajtów

<?for($t=$_GET[t];$i<181;$s+=$v,$i+=2)$t[$i+20]=($v=$t[$i])*($z=$t[$i+2])>0&$i!=18?($v+$z)%3^3:" ";echo chunk_split($t.str_pad($s,8," ",0),19);
Jörg Hülsermann
źródło
0

JavaScript (ES6), 112 100 96 bajtów

Pobiera tablicę jako dane wejściowe i rekurencyjnie tworzy trójkąt oddzielony przecinkami.

f=(s,p=`
`,S=0)=>p+(s[0]?s+f(s.map((v,i)=>(S+=v,v^s[i-1]||v)).slice(1),p+' ',S):(p+S).slice(-9))

console.log(f([1,2,3,3,1,3,1,3,1,2])); // reference example
console.log(f([3,3,2,1,3,1,2,1,2,1])); // random example
console.log(f([1,1,1,1,1,1,1,1,1,1])); // all ones (test case for sum < 100)

Arnauld
źródło