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.


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.


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)

(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

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              

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 .


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.


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..]

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!


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

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!


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.


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


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)

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

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.


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,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.