Czy się przewrócę?

36

Przegląd

Biorąc pod uwagę ciąg 3 linii, dowiedz się, czy struktura spada w lewo, balansuje lub spada w prawo.

Struktura wejściowa

Możesz sobie wyobrazić tę konstrukcję jako metalowy pręt z elementami na górze, wszystkie wyważone na pionowym pręcie.

1  7 4        a
===============
        |

Pierwszy wiersz to pozycje. Waga każdego przedmiotu jest obliczana jako wartość ascii znaku minus 32. (Znaki poniżej 32 nie są brane pod uwagę, a spacje ważą 0). Pamiętaj, że siła przedmiotu na pręcie to jego waga razy odległość do punktu obrotu.

Druga linia to pręt. Każda długość pręta sama waży 1 jednostkę. Ta linia jest wyłącznie równa znakom ( =).

Trzecia linia to punkt obrotu. Można go umieścić w dowolnym miejscu i jest reprezentowany przez pewną liczbę spacji, po których występuje pojedynczy |znak pipe ( ).

Przykłady

Wkład:

=====
  |

Wyjście: Balance

Wkład:

=====
   |

Wyjście: spada w lewo

Wkład:

    %
=====
   |

Wyjście: Balance (ponieważ %waży wystarczająco dużo, aby przeciwdziałać ciężarowi lewej strony pręta)

Wkład:

 aa
=======
   |

Wyjście: spada w prawo (ponieważ apo prawej stronie znajduje się dalej od punktu obrotu)

Wkład:

1  7 4        A
===============
        |

Wyjście: spada w lewo

Wkład:

1  7 4        a
===============
        |

Wyjście: spada w prawo (małe litery są ciężkie!)

Wkład:

            $ ~
===============
             |

Wyjście: Balance

Notatki

  • Końcowe białe znaki są dozwolone, wiodące białe znaki nie.
  • Twój program może wyświetlać dane w dowolnym formacie, pod warunkiem, że istnieją 3 różne wyjścia dla lewego, balansu i prawego.
  • Twój program musi zaakceptować format pokazany jako dane wejściowe.
Daffy
źródło
1
Ściśle związany
Luis Mendo,
Czy program może przyjmować trzy wiersze jako trzy osobne ciągi znaków (np. Jako trzy argumenty funkcji lub jako lista trzech elementów)?
notjagan
@notjagan Dane wejściowe muszą być pojedynczym ciągiem oddzielonym znakami nowego wiersza.
Daffy,
Powiązany , możliwy duplikat.
xnor
@xnor Nie jest dupkiem, ponieważ to pytanie dotyczy tylko wielkich liter, a jego celem jest znalezienie punktu przestawnego. Moje pytanie dotyczy wszystkich znaków ascii> = 32, a mój dostarcza oś obrotu i pyta, czy struktura się przewróci. Zasadniczo odwrotność tego, który połączyłeś.
Daffy

Odpowiedzi:

8

JavaScript (ES6), 116 111 108 106 bajtów

-5 bajtów przez zsumowanie przez eval(array.join`+`)zamiast array.reduce().
-3 bajty domyślnie 1zamiast 32 - 31, co pozwala na usunięcie nawiasów.
-2 bajty, ponieważ punkt obrotu jest długością ostatniej linii - 1

(s,[t,r,b]=s.split`
`)=>Math.sign(eval([...r].map((_,i)=>(t.charCodeAt(i)-31||1)*(i-b.length+1)).join`+`))

Wyjścia -1, 0lub 1na lewo, zrównoważony, lub w prawo, odpowiednio. Skończyło się podobnie do odpowiedzi pytona Chasa Browna , więc trafia się tam.

Można zapisać 4 bajty, jeśli pierwsza linia jest wypełniona, aby dopasować długość pręta za pomocą
(31-t.charCodeAt(i))*(b.length+~i).

Test Snippet

Obejmuje dodatkowe dane wyjściowe ( Left/ Balanced/ Right) wraz z liczbą.

f=
(s,[t,r,b]=s.split`
`)=>Math.sign(eval([...r].map((_,i)=>(t.charCodeAt(i)-31||1)*(i-b.length+1)).join`+`))
<textarea id=I rows=3 cols=20></textarea><br><button onclick="O.value=I.value?`${x=f(I.value)} (${['Left','Balanced','Right'][x+1]})`:''">Run</button> <input id=O disabled>

Kolejna metoda 106-bajtowa

(s,[t,r,b]=s.split`
`)=>Math.sign(eval(r.replace(/./g,(_,i)=>"+"+(t.charCodeAt(i)-31||1)*(i-b.length+1))))

Zamiast joiningerować w tablicę +s, tworzymy ciąg liczb, każdy z prefiksem +. Prowadzenie +zostaje zignorowane.

Justin Mariner
źródło
1
Myślę, że (b.length+~i)może pomóc uratować bajt. (Również nie rozumiem, dlaczego masz ||1.)
Neil
1
@ Neil b.length+~izwraca minus i-b.length+1; to mogłoby pomóc, gdybym mógł zaprzeczyć drugiej części. A jeśli chodzi o to ||1, to dlatego, że zakładałem, że pierwsza linia nie była wyściełana, aby pasowała do długości wędki, więc t.charCodeAt(i)wrócę NaNpoza koniec pierwszej linii.
Justin Mariner
Nie zastanawiałem się, czy nie wypróbować nie wypełnionego testu; dzięki za wyjaśnienie.
Neil
3

Python 2 , 112 110 bajtów

def f(s):w,b,p=s.split('\n');return cmp(sum((ord((w+' '*-~i)[i])-31)*(i-p.find('|'))for i in range(len(b))),0)

Wypróbuj online!

EDYCJA: W końcu udało się wyeliminować enumeratei rjustza marne 2 bajty ... meh!

Wciąga sznur; wyjścia -1,0 lub 1 dla odpowiednio spadków w lewo, równowagi, spadków odpowiednio w prawo.

Pierwszy przebieg przy 112 bajtach to:

def f(s):w,b,p=s.split('\n');return cmp(sum((ord(c)-31)*(i-p.find('|'))for i,c in enumerate(w.rjust(len(b))),0)
Chas Brown
źródło
(ord(c)-31)Zajęło mi trochę czasu, aby zdać sobie sprawę, że tak naprawdę obejmuje to ciężar samej wędki wraz z przedmiotami. Bardzo mądry!
Daffy,
1
Zgodnie meta , można wymienić returnz printna -1 bajt (choć tak naprawdę nie grać ładnie z aktualnym kodem TIO).
notjagan
3

Haskell, 212 171 bajtów (188 jeśli weź dane wejściowe jako jeden ciąg)

o!p=map(fst)(zip[p-0,p-1..]o)
x#p=sum(zipWith(\c w->(max(fromEnum c-32)0)*w)x(x!p))+sum(x!p)
x?c=length(takeWhile(==c)x)

Wariant 171 bajtów

r a b c=signum(take(b?'=')(a++repeat ' ')#(c?' '))

Wariant 188 bajtów

x%y=lines x!!y
r i=signum(take(i%1?'=')(i%0++repeat ' ')#(i%2?' '))

Wyjaśnienie

o!p=map(fst)(zip[p-0,p-1..]o)        Creates weights coefs list. 
                                     o - list, p - pivot position
                                     for list "abcdf" and p=3 (pivot under 'd')
                                     outputs [3,2,1,0,-1]

x#p                                  Calculates total balance
                                     x-list of "objects" on lever, p-pivot place
  sum(zipWith                        sum of zipped lists
   (\c w->(max(fromEnum c-32)0)*w)   weight of ascii "object" times
                                     distance from pivot
    x(x!p))                          x-ascii objects, 
                                     (x!p)-distances list(weight coefs)
  +sum(x!p)                          balance of lever ("==") itself

x?c=length(takeWhile(==c)x)          length of list before non c element met
                                     used to find '|' position
                                     and length of "===" lever
                                     before right whitespaces met

r a b c=                             Sums it all up =)
                                     a-ascii objects, b-lever, c-pivot line
   signum(                           1-tips left, 0-balance, -1-tips right
     take(b?'=')(a++repeat ' ')      takes all object on lever 
                                     plus whitespaces up to length of the lever
      #                              calculate the balance
       (c?' ')                       determine place of pivot
Sergii Martynenko Jr
źródło
1
Możesz użyć fromEnumzamiast ordi upuścić import. cmożna go uprościć do c p=max(ord p-32)0(lub z fromEnum), a ponieważ używasz go tylko raz, wstaw go.
nimi
Lub możesz dodać (Lambdabot) do swojego tytułu, to importuje prawie wszystko, czego potrzebujesz, zobacz tutaj .
ბიმო
1
Funkcję cmożna nawet uprościć (znaki poniżej 32 nie są brane pod uwagę) c p=ord p-32. pJest także w zasadzie length(minus 1), więc też p x=length x-1by działał (i można go również wstawić). Zobacz także moje rozwiązanie, w jaki sposób korzystam signum- możesz zrobić, r o l s = signum $ 2 * z ...które zwraca 0,1,-1B, L, R.
ბიმო
1
Poza tym to rozwiązanie wydaje się nie sprawdzać przypadków testowych [3,4,7]i przyjmuje 3 ciągi zamiast jednego. (patrz lines).
ბიმო
1
Oto wersja z kilkoma zastosowanymi wskazówkami (oszczędza 29 bajtów;)).
ბიმო
2

Galaretka , 30 bajtów

O_31×J_¥A+\sṪ€µ÷ḢṪ_2Ṡ
ỴṪLç@ỴḢ$

Pakiet testowy

Wyjścia 0 dla zbalansowanego, 1 dla prawego i -1 dla lewego.

Jak to działa

O_31×J_¥A+\sṪ€µ÷ḢṪ_2Ṡ - helper function. Arguments position of pivot and first line
O                        - char codes of first line
 _31                     - subtract 31 to get weight
    ×                    - elementwise product with:
     J_¥                 - distances from the pivot
        A                - absolute value
         +\              - cumulative sum
           s             - split to get [[...,left weight],...,[..., right + left weight]]
            Ṫ€           - last element of each sublist: [left weight, ... right weight]
              µ÷Ḣ        - get ratio of each element over left weight: ratio n indicates
                              right + left = n × left ===> right = left if n = 2
                 _2      - subtract 2: positive is right>left and negative is right<left
                   Ṡ     - return the sign of this


ỴṪLç@ỴḢ$              - main link. Argument: 3 line string.
   ç@                  - apply helper function with arguments:
Ỵ                        - split by linefeeds
 Ṫ                       - last line
  L                      - length (returns position of pivot)
       $               - and
     Ỵ                   - split by linefeeds
      Ḣ                  - first line              
fireflame241
źródło
2

Galaretka , 24 bajty

ṪO_31
ỴµṪLạЀṪL$×Çṣ0S€IṠ

Wypróbuj online!

-1do opadania w lewo, 0do równoważenia, 1do opadania w prawo (pełny program).
[-1]do opadania w lewo, [0]do równoważenia, [1]do opadania w prawo (funkcja).

Pierwsza linia musi mieć końcowe spacje, ostatnia linia nie może.

Objaśnienie (zaczynamy od dolnej linii):

Po pierwsze, pracujemy z poszczególnymi liniami, więc musimy jakoś je zdobyć. To jest praca dla . Następnie musimy traktować \nwersję -split wejścia tak, jakby była to oryginalna, więc używamyµ aby monadyczny łańcuch zastosowano do bieżącej wartości.

Teraz zaczynamy prawdziwą pracę, a naszą pierwszą pracą będzie obliczanie współczynników wag. Zasadniczo jest to zakres [odległość od skrajnej lewej do osi obrotu .. 0 .. odległość od osi do skrajnej prawej strony]. Przede wszystkim musimy znaleźć indeks przestawny oparty na 1, który jest zasadniczo długością ostatniego wiersza bez spacji końcowych. Więc wstawiamy ostatnią linię (linię przestawną) z naszej oryginalnej listy , ponieważ nie będziemy jej już potrzebować, a następnie bierzemy jej długość L. Następnie musimy wziąć długość wędki, dla której robimy to samo z ostatnią linią (linią wędki) ṪL$. Wreszcie, aby uzyskać zasięg, mapujemy | x - y | na [1.. długość produktu], gdzie x jest indeksem przestawnym, ayto każdy element listy, na której mapujemy. Robimy to za pomocą ạЀ, gdzie oblicza | x - y | i Ѐtworzy zakres od 1 do długości pręta włącznie. Teraz będziemy mieć odpowiedni zasięg.

Następnie musimy pomnożyć każdą liczbę całkowitą, reprezentującą kawałek pręta, z odpowiadającym mu ciężarem. Aby obliczyć wagi, używamy Ç, przechodząc do górnej linii naszego kodu. Bierzemy pozostałą linię , jej kody za pomocą O, a następnie obliczamy x - 31 za pomocą _31, gdzie x jest każdym kodem znaków. Następnie przypisujemy spację do wagi 1 (0 + kawałek pręta = 1), !do wagi 2 (1 + 1) itd. Skończyliśmy z górną linią, więc teraz Çzwróciłoby listę wag, które mnożymy przez odpowiedni liczby całkowite reprezentujące kawałki pręta z ×.

Następnie dzielimy się ṣ0na punkt obrotu reprezentowany przez 0 (ponieważ żadna waga nie wpłynie na wynik), w wyniku czego powstaje lista postaci [[1. waga, 2. waga ... waga tuż przed osią obrotu] , [waga tuż po osi obrotu, waga po poprzedniej ... ostatniej wadze]]. Te listy reprezentują boki pręta, lewy i prawy. Teraz sumujemy każdą z list za pomocą, S€aby uzyskać całkowitą wagę z każdej strony, i używamy Ido wzięcia delty, która będzie ujemna, jeśli lewa strona jest cięższa, zero, jeśli są równe, i dodatnia, jeśli prawa strona jest cięższa . Tak więc, aby przywrócić wynik końcowy przy użyciu tego poprawnie na naszą korzyść, bierzemy znak z .

Erik the Outgolfer
źródło
2

APL (Dyalog) , 43 bajty *

{×(¯31+⎕UCS⊃⍵)+.×(⍳≢⊃⍵)-'|'⍳⍨⊃⌽⍵}⎕TC[2]∘≠⊆⊢

Wypróbuj online!

⊆⊢ podziel argument na ciągi znaków, które są

⎕TC[2]∘≠ różni się od 2- giej litery C terminala sterującego (podawanie liniowe ) **

{} Zastosuj następującą anonimową funkcję na liście ciągów:

⊃⌽⍵ w pierwszym ciągu odwróconej listy (tj. ostatnim)

'|'⍳⍨ znajdź końcówkę punktu obrotu

()- Odejmij to od następującej listy:

  ⊃⍵ pierwszy ciąg

   jego długość

   wszystkie ɩ ndices tego

()+.×  Suma ważona z tymi wagami i następującymi wartościami:

  ⊃⍵ pierwszy ciąg

  ⎕UCS Punkty kodu w U niversal C haracter S i

  ¯31+ dodaj ujemny trzydzieści jeden (32 dla wymaganego przesunięcia minus jeden dla pręta)

× podpis tego


* Dla 1 bajtu na znak, użyj {×(¯31+⎕UCS↑⍵)+.×(⍳≢↑⍵)-'|'⍳⍨↑⌽⍵}⎕TC[3]∘≠⊂⊢z ⎕ML←3. Wypróbuj online!
** ⎕TCjest przestarzałe i używane tutaj tylko do celów golfowych. W kodzie produkcyjnym należy użyć ⎕UCS 10.

Adám
źródło
2

Haskell (Lambdabot), 142 bajty

l=length
g[a,c,b]=splitAt(l b)$a++(' '<$[1..l c-l a])
k e=sum$zipWith((*).(-31+).ord)e[1..]
f=signum.uncurry(-).(k.drop 1.reverse***k).g.lines

Wypróbuj online!

Wersja bez golfa:

-- for readability, allows reading top-down/left-right
(.>) = flip (.)

ungolfed =
     lines                                 -- separate out lines into..
  .> (\[a,b,c] ->                          -- a,b,c (first,second,third)
                                           -- ' ' pad the first line & split on pivot
       splitAt (length c) (a ++ replicate (length b - length a) ' ')
     )
  .> (weight.drop 1.reverse *** weight)    -- reverse left half, drop element above pivot & get weight for both
  .> uncurry (-)                           -- subtract right from left
  .> signum                                -- get sign

-- get ord of the character subtract 31 ('=' char from bar),
-- then multiply with scales ([1..]) and sum it all up
weight es = sum $ zipWith (ord .> subtract 31 .> (*)) es [1..]
ბიმო
źródło
2

Python 2 , 90 bajtów

def f(s):L=len(s)/3;print cmp(sum((ord(s[i])-31)*(i-s[-L:].find('|'))for i in range(L)),0)

Oczekuje, że linie wejściowe zostaną wypełnione (spacjami) do odpowiedniej długości. Wyjścia -1dla spadków w lewo , 0dla zrównoważonych i 1dla spadków w prawo .

Wypróbuj online!


94 bajty

Dla +4 bajtów możemy mieć wersję, która za pomocą whilepętli wymaga linii rozebranych , a nie linii dopełnionych :

def f(s):
 i=r=0
 while''<s[i]:r+=(ord(s[i])-31)*(i-s[-3::-1].find('='));i+=1
 print cmp(r,0)

Wypróbuj online!

FlipTack
źródło
1

Rubinowy, 543 bajty

def willittip(s)
leftw=0;
rightw=0;
arr=[];
fields=s.split("\n")
pos=fields[2].index("|")
fields[0].split("").each do |i|
arr << i.ord-32
end
arr[pos+1..-1].each_with_index do |x,y|
rightw=rightw+1
if x>0
if pos>0
rightw=rightw+x*(pos-y).abs
else
rightw=rightw+x
end
end
end
arr[0..pos-1].each_with_index do |x,y|
leftw=leftw+1
if x>0
if pos>0
leftw=leftw+x*(pos-y).abs
else
leftw=leftw+x
end
end
end
if leftw==rightw
return "Equal"
elsif leftw<rightw
return "Right"
elsif leftw>rightw
return "Left"
end
end
KittenDev
źródło
10
Witamy w PPCG! : D Celem wyzwań związanych z golfem jest, aby Twój kod był jak najmniejszy. Możesz zmniejszyć rozmiar kodu, nadając wszystkim zmiennym i nazwom funkcji jeden znak oraz usuwając białe znaki, jeśli to możliwe.
Daffy
1

C (gcc) , 106107 121 123 124 129 131 bajty

c,b,l,i;f(char*a){l=strlen(a)/3;for(i=b=c=0;32/a[l*2+c];++c);for(;i<l-1;b+=(a[i]-31)*(i++-c));a=b>0?2:!b;}

Zwraca 0 za upadek w lewo, 1 za równowagę i 2 za upadek w prawo.

Wymagaj, aby wszystkie trzy linie miały tę samą długość i kończą się, \naby określić długość łańcucha.

Wypróbuj online!

Keyu Gan
źródło
1

Mathematica, 91 92 bajty

Sign[(v=(g=ToCharacterCode)@#&@@(d=#~StringSplit~"
")-31).(Range@(l=Length)@v-l@g@Last@d)]&

Pierwsza linia powinna mieć tę samą długość z wędką. Trzeci wiersz nie powinien zawierać spacji końcowych.

Zwróć -1, 0, 1 za upadek w lewo, równowagę i upadek w prawo.

Keyu Gan
źródło
1

C # (.NET Core) , 127 95 90 + 18 = 108 bajtów

Dla tej funkcji pierwsza linia musi być odpowiednio wypełniona spacjami, aby mieć taką samą długość jak pręt, a trzecia linia nie może mieć przestrzeni próbnych. Te warunki są dozwolone (patrz komentarze do pytania).

s=>s.Split('\n')[0].Select((c,i)=>(c-31)*(i-s.Split('\n')[2].Length+1)).Sum().CompareTo(0)

Wypróbuj online!

Wyjścia:

-1 dla końcówki w lewo
0 dla równowagi
1 dla końcówki w prawo

raznagul
źródło
1

Python 3, 217 bajtów

Działa również w Pythonie 2.7

def f(s):i,b,p=s.split('\n');c=p.find('|');l=sum((ord(e)-32)*(c-i.find(e))for e in i[:c])+sum(x for x in range(1,c+1));r=sum((ord(e)-32)*i[c:].find(e)for e in i[c:])+sum(x for x in range(len(b[c:])));return(l>r)-(r>l)

Zwraca 1 dla lewej strony, -1 dla prawej strony lub zero, jeśli jest zrównoważony.

Wersja do odczytu:

def f(s):
    i,b,p = s.split('\n')
    c = p.find('|')

    l = sum((ord(e)-32)*(c-i.find(e))for e in i[:c])+sum(x for x in range(1, c+1))
    r = sum((ord(e)-32)*i[c:].find(e)for e in i[c:])+sum(x for x in range(len(b[c:])))

    return(l>r)-(r>l)
wegetariańskie
źródło
1
Nie potrzebujesz sum([...]), możesz po prostu miećsum(...)
Mr. Xcoder
@Daffy powinno to być w 100% zgodne ze specyfikacją i wszystkimi podanymi przykładowymi danymi wejściowymi. Jeśli się zgadzasz, daj mi znać, abym mógł go dalej zoptymalizować. Dziękuję Ci.
veganaiZe
@ veganaiZe Przeszedł wszystkie moje testy, wygląda dobrze! :)
Daffy,
1
Rzeczy, które ją skracają: i[c:].find(e)można i.find(e,c), używaj i,m,n=s.split('\n')i unikaj sw ogóle potrzeby , używaj, return 2*(r>l) or l>raby radykalnie obniżyć koszty testu na końcu (wartość zwracana jest liczbowo równoważna, ale jest Truezamiast 1i Falsezamiast 0), lub naprawdę, użyj innego zestawu zwrotu wartości i wykonaj, return (l>r)-(r>l)aby zwrócić 1, 0 lub -1, tak jak cmpzrobiła to stara funkcja.
ShadowRanger,
Dzięki ShadowRanger, Mr. Xcoder i Daffy! @ShadowRanger Musiałem trzymać się tego, i[c:]ponieważ krótsza droga spowodowała dziwny problem off-by-one dla niektórych danych wejściowych w rogu (spróbuj umieścić |dokładnie na środku - powyżej paska).
veganaiZe
1

PHP, 105 bajtów

for([$a,$b,$c]=explode("
",$argn);$b[$i];)$w+=(strpos($c,"|")-$i++)*8*(max(1,ord($a[$i])-31));echo$w<=>0;

drukuje -1/ 0/ 1dla left / balance / right. Uruchom jako potok z -nRlub spróbuj online .

awaria

for([$a,$b,$c]=explode("\n",$argn); # import input
    $b[$i];)                        # loop through bar
    $f+=                                # add to force:
        ($i-strpos($c,"|"))             # distance (<0 if left, >0 if right of pivot)
        *8                              # *8
        *(max(1,ord($a[$i++])-31));     # *weight
echo$f<=>0;                         # print -1 if $f<0, 1 if $f>0, 0 if $f==0
Tytus
źródło
1

Węgiel drzewny , 31 bajtów

A⁰ξFLθA⁺ξ×⁻ι⌕ζ|⁻℅§θι³¹ξI⁻›ξ⁰‹ξ⁰

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjścia 0 dla równowagi lub -1 lub 1 dla spadku w lewo lub w prawo. Edycja: Zmiany w węglu drzewnym oznaczają teraz, że ≔ΣEθ×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰działa na 24 bajty: Wypróbuj online! Link jest do pełnej wersji kodu. Uwaga: Obie odpowiedzi wymagają wprowadzania wypełnionego, ale można je dostosować tak, aby akceptowały dane niepodawane przy koszcie 3 bajtów: ≔⁰ξFLη≔⁺ξ×⁻ι⌕ζ|⁻℅§◨θLηι³¹ξI⁻›ξ⁰‹ξ⁰ Wypróbuj online! ≔ΣE◨θLη×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰ Wypróbuj online! Linki są do pełnej wersji kodu.

Neil
źródło
Warto o tym wspomnieć, ponieważ oczekuje się, że wiersze wejściowe zostaną wypełnione do odpowiedniej długości spacjami, więc niepakowane dane wejściowe mogą nie działać.
FlipTack,
@FlipTack Jeszcze lepiej, opracowałem wersje, które akceptują niepakowane dane wejściowe.
Neil,