Apakah saya akan memberi tip?


36

Ikhtisar

Diberikan string 3 baris, cari tahu apakah struktur jatuh ke kiri, keseimbangan, atau jatuh ke kanan.

Struktur input

Anda dapat membayangkan strukturnya sebagai batang logam dengan benda-benda di atasnya, semuanya seimbang di atas batang vertikal.

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

Baris pertama adalah item. Bobot masing-masing item dihitung sebagai nilai ascii dari karakter minus 32. (Karakter di bawah 32 tidak dipertimbangkan dan spasi menimbang 0). Perlu diingat bahwa kekuatan item pada batang adalah beratnya kali jarak ke titik pivot.

Baris kedua adalah tongkat. Setiap batang memiliki berat 1 unit dengan sendirinya. Baris ini secara eksklusif sama dengan tanda ( =).

Baris ketiga adalah titik pivot. Ini dapat ditempatkan di mana saja, dan diwakili oleh sejumlah spasi diikuti oleh karakter pipa tunggal ( |).

Contohnya

Memasukkan:

=====
  |

Output: Saldo

Memasukkan:

=====
   |

Output: Jatuh ke kiri

Memasukkan:

    %
=====
   |

Keluaran: Saldo (Karena %beratnya cukup untuk menetralkan bobot sisi kiri batang)

Memasukkan:

 A A
=======
   |

Output: Jatuh tepat (karena adi sebelah kanan lebih jauh dari titik pivot)

Memasukkan:

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

Output: Jatuh ke kiri

Memasukkan:

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

Output: Jatuh tepat (huruf kecil berat!)

Memasukkan:

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

Output: Saldo

Catatan

  • Trailing whitespace diizinkan, whitespace terkemuka tidak diizinkan.
  • Program Anda dapat menampilkan dalam format apa pun yang Anda suka, selama ada 3 keluaran berbeda untuk kiri, keseimbangan, dan kanan.
  • Program Anda harus menerima format yang ditampilkan sebagai input.


Bisakah program mengambil tiga baris sebagai tiga string terpisah (misalnya tiga argumen untuk suatu fungsi atau sebagai daftar tiga elemen)?
notjagan

@ notjagan Input harus berupa string tunggal yang dipisahkan oleh karakter baris baru.
Daffy

Terkait , kemungkinan penipuan.
xnor

@ xnor Bukan penipuan karena pertanyaan itu hanya berurusan dengan huruf besar, dan tujuannya adalah untuk menemukan pivot. Pertanyaan saya adalah tentang semua karakter ascii> = 32, dan milik saya memasok pivot dan menanyakan apakah strukturnya akan jatuh. Pada dasarnya kebalikan dari yang Anda tautkan.
Daffy

Jawaban:


8

JavaScript (ES6), 116 111 108 106 byte

-5 byte dengan menjumlahkan melalui eval(array.join`+`)alih-alih array.reduce().
-3 byte secara default menjadi 1alih-alih 32 - 31, memungkinkan tanda kurung dihapus.
-2 byte karena titik pivot adalah panjang dari baris terakhir - 1

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

Output -1, 0atau 1, untuk meninggalkan, seimbang, atau kanan, masing-masing. Akhirnya mirip dengan jawaban python Chas Brown , jadi kredit masuk ke sana.

Dapat menghemat 4 byte jika baris pertama diisi agar sesuai dengan panjang batang dengan menggunakan
(31-t.charCodeAt(i))*(b.length+~i).

Cuplikan Tes

Termasuk output tambahan ( Left/ Balanced/ Right) bersama dengan jumlahnya.

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>

Metode 106 byte lainnya

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

Alih-alih joinmenggunakan array di +s, kami membuat string angka, masing-masing diawali oleh +. Pemimpin +diabaikan.


1
Saya pikir (b.length+~i)mungkin membantu menghemat satu byte. (Juga saya tidak mengerti mengapa Anda memilikinya ||1.)
Neil

1
@Neil b.length+~imengembalikan negatif dari i-b.length+1; itu bisa membantu jika saya bisa meniadakan bagian lain. Adapun ||1, itu karena saya berasumsi baris pertama tidak empuk untuk mencocokkan panjang batang, jadi t.charCodeAt(i)akan kembali NaNmelampaui ujung baris pertama.
Justin Mariner

Saya belum mencoba uji kasus non-empuk; terima kasih sudah menjelaskan.
Neil

3

Python 2 , 112 110 byte

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)

Cobalah online!

EDIT: Akhirnya berhasil menghilangkan enumeratedan rjustuntuk 2 byte ... meh!

Dibawa dalam sebuah string; output -1,0, atau 1 untuk jatuh ke kiri, saldo, jatuh ke kanan, masing-masing.

Pass pertama pada 112 byte adalah:

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)Butuh beberapa saat untuk menyadari bahwa ini sebenarnya menggabungkan berat batang itu sendiri bersama dengan barang-barang. Sangat pintar!
Daffy

1
Sesuai meta , Anda dapat mengganti returndengan printuntuk -1 byte (meskipun tidak benar-benar bermain baik dengan kode TIO saat ini).
notjagan

3

Haskell, 212 171 byte (188 jika mengambil input sebagai satu string)

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)

Varian 171 byte

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

Varian 188 byte

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

Penjelasan

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
Anda bisa menggunakan dan fromEnumbukannya ordmenjatuhkan import. cdapat disederhanakan menjadi c p=max(ord p-32)0(atau dengan fromEnum) dan karena Anda hanya menggunakannya sekali, sebariskan.
nimi

Atau Anda dapat menambahkan (Lambdabot) ke judul Anda, ini mengimpor hampir semua yang Anda butuhkan, lihat di sini .
ბიმო

1
Fungsi cini bahkan dapat disederhanakan (karakter di bawah 32 tidak dianggap) lebih jauh c p=ord p-32. Juga ppada dasarnya length(minus 1), jadi p x=length x-1akan bekerja juga (dan Anda bisa inline juga). Juga lihat solusi saya, bagaimana saya menggunakan signum- Anda bisa melakukan r o l s = signum $ 2 * z ...yang mengembalikan 0,1,-1untuk B, L, R.
ბიმო

1
Terlepas dari itu, bahwa solusi ini tampaknya gagal untuk menguji kasus [3,4,7]dan mengambil 3 Strings daripada satu (lihat lines).
ბიმო

1
Berikut ini adalah versi dengan beberapa tips yang diterapkan (menghemat 29 byte;)).
ბიმო

2

Jelly , 30 byte

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

Test Suite

Output 0 untuk seimbang, 1 untuk kanan, dan -1 untuk kiri.

Bagaimana itu bekerja

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

Jelly , 24 byte

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

Cobalah online!

-1untuk jatuh ke kiri, 0untuk menyeimbangkan, 1untuk jatuh ke kanan (program penuh).
[-1]untuk jatuh ke kiri, [0]untuk menyeimbangkan, [1]untuk jatuh ke kanan (fungsi).

Baris pertama harus memiliki spasi tambahan, baris terakhir tidak boleh.

Penjelasan (kami mulai dengan garis bawah):

Pertama-tama, kami bekerja dengan masing-masing jalur, jadi kami harus mendapatkannya entah bagaimana. Itu pekerjaan untuk . Kemudian, kita perlu memperlakukan \nversi -split dari input seolah-olah itu adalah input asli, jadi kita gunakan µuntuk membuat rantai monadik yang diterapkan pada nilai saat ini.

Sekarang kita mulai pekerjaan nyata, dan pekerjaan pertama kita akan menghitung faktor-faktor bobot. Pada dasarnya ini adalah kisaran [jarak dari paling kiri ke pivot.0.0. Jarak dari pivot ke ujung kanan]. Pertama-tama, kita harus menemukan indeks pivot berbasis 1, yang pada dasarnya adalah panjang dari baris terakhir tanpa spasi tambahan. Jadi kami menghapus baris terakhir (pivot line) dari daftar asli kami dengan , karena kami tidak akan membutuhkannya lagi, dan kemudian kami memanjangnya L. Kita kemudian perlu mengambil panjang batang, yang dengannya kita melakukan hal yang sama dengan garis sekarang-terakhir (garis batang) dengan ṪL$. Akhirnya, untuk mendapatkan jangkauan, kami memetakan | x - y | ke [1..panjang produk], di mana x adalah indeks pivot dan yadalah setiap elemen dari daftar yang kita petakan. Kami melakukan ini menggunakan ạЀ, di mana menghitung | x - y | dan Ѐmembuat rentang dari 1 hingga dan termasuk panjang batang. Sekarang kita akan memiliki rentang yang kita inginkan.

Setelah itu, kita harus melipatgandakan setiap bilangan bulat, mewakili sepotong batang, dengan bobot yang sesuai. Untuk menghitung bobot, kami menggunakan Ç, pergi ke baris teratas dari kode kami. Kami mengambil baris yang tersisa dengan , kode kodenya O, dan kemudian kami menghitung x - 31 menggunakan _31, x menjadi masing-masing karakter sandi. Kami kemudian menetapkan ruang untuk bobot 1 (0 + potongan batang = 1), !untuk bobot 2 (1 + 1), dll. Kami selesai dengan baris teratas, jadi sekarang Çakan mengembalikan daftar bobot, yang kami kalikan dengan yang sesuai bilangan bulat mewakili potongan batang dengan ×.

Setelah itu, kami berpisah dengan ṣ0pada pivot point, diwakili oleh 0 (karena bobot apa pun tidak akan mempengaruhi hasilnya), menghasilkan daftar bentuk [[bobot 1, bobot 2 ... berat sesaat sebelum poros] , [berat setelah pivot, berat setelah pivot sebelum ... berat terakhir]]. Daftar itu mewakili sisi-sisi batang, kiri dan kanan. Kami sekarang menjumlahkan setiap daftar yang digunakan S€untuk mendapatkan bobot total di setiap sisi, dan menggunakan Iuntuk mengambil delta, yang akan menjadi negatif jika sisi kiri lebih berat, nol jika bobotnya sama, dan positif jika sisi kanan lebih berat . Jadi, untuk mengembalikan hasil akhir menggunakan ini dengan benar untuk keuntungan kami, kami menerima tandanya .


2

APL (Dyalog) , 43 byte *

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

Cobalah online!

⊆⊢ mempartisi argumen menjadi karakter yang dijalankan

⎕TC[2]∘≠ berbeda dengan 2 nd T erminal C ontrol karakter (linefeed) **

{... } terapkan fungsi anonim berikut pada daftar string:

⊃⌽⍵ dalam string pertama dari daftar terbalik (yaitu yang terakhir)

'|'⍳⍨ temukan ɩ ndex dari titik pivot

(... )- kurangi itu dari daftar berikut:

  ⊃⍵ string pertama

   panjangnya

   semua d saran dari itu

(... )+.× jumlah tertimbang dengan bobot tersebut dan nilai berikut:

  ⊃⍵ string pertama

  ⎕UCS poin kode dalam U niversal C haracter S et

  ¯31+ tambahkan negatif tigapuluh satu (32 untuk offset yang dibutuhkan minus satu untuk batang)

× signum itu


* Untuk 1 byte per karakter, gunakan {×(¯31+⎕UCS↑⍵)+.×(⍳≢↑⍵)-'|'⍳⍨↑⌽⍵}⎕TC[3]∘≠⊂⊢dengan ⎕ML←3. Cobalah online!
** ⎕TCsudah usang dan digunakan di sini hanya untuk tujuan bermain golf. Dalam kode produksi, seseorang harus menggunakan ⎕UCS 10.


2

Haskell (Lambdabot), 142 byte

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

Cobalah online!

Versi tidak disatukan:

-- 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 byte

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

Mengharapkan jalur input akan diisi (dengan spasi) dengan panjang yang benar. Output -1untuk jatuh kiri , 0untuk seimbang , dan 1untuk jatuh tepat .

Cobalah online!


94 byte

Untuk +4 byte kita dapat memiliki versi yang, menggunakan whileloop, membutuhkan garis-garis yang dilucuti daripada garis-garis empuk :

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)

Cobalah online!


1

Ruby, 543 byte

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
Selamat datang di PPCG! : D Tujuan dari tantangan kode-golf adalah membuat kode Anda sekecil mungkin. Anda dapat mengurangi ukuran kode Anda dengan membuat semua variabel dan nama fungsi menjadi satu karakter, dan dengan menghapus spasi bila mungkin.
Daffy

1

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

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;}

Kembalikan 0 untuk jatuh ke kiri, 1 untuk keseimbangan dan 2 untuk jatuh ke kanan.

Memerlukan ketiga garis untuk memiliki panjang yang sama dan selesai dengan \nuntuk menentukan panjang tali.

Cobalah online!


1

Mathematica, 91 92 byte

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

Baris pertama harus memiliki panjang yang sama dengan batang. Baris ketiga tidak boleh mengandung spasi tambahan.

Kembali -1, 0, 1 untuk jatuh ke kiri, keseimbangan dan jatuh ke kanan.


1

C # (.NET Core) , 127 95 90 + 18 = 108 byte

Untuk fungsi ini, baris pertama harus empuk dengan spasi yang sama dengan panjang batang dan baris ketiga tidak boleh memiliki ruang trialing. Ketentuan ini diizinkan (lihat komentar pertanyaan).

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

Cobalah online!

Output:

-1 untuk tip kiri
0 untuk saldo
1 untuk tip kanan


1

Python 3, 217 byte

Juga berfungsi di Python 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)

Mengembalikan 1 untuk sisi kiri, -1 untuk sisi kanan, atau nol jika seimbang.

Versi yang dapat dibaca:

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
Anda tidak perlu sum([...]), Anda cukup memilikisum(...)
Tn. Xcoder

@Daffy ini harus 100% sesuai dengan spesifikasi Anda dan semua input contoh yang diberikan. Jika Anda setuju, beri tahu saya agar saya dapat mengoptimalkannya lebih lanjut. Terima kasih.
veganaiZe

@veganaiZe Melewati semua tes saya, terlihat bagus! :)
Daffy

1
Hal-hal untuk dipersingkat: i[c:].find(e)bisa i.find(e,c), gunakan i,m,n=s.split('\n')dan hindari kebutuhan ssama sekali, gunakan return 2*(r>l) or l>runtuk secara dramatis mengurangi biaya pengujian pada akhir (nilai pengembalian setara secara numerik, tetapi Truealih - alih 1dan Falsebukan 0), atau benar-benar, gunakan rangkaian pengembalian yang berbeda nilai dan lakukan return (l>r)-(r>l)untuk mengembalikan 1, 0 atau -1 seperti cmpfungsi lama lakukan.
ShadowRanger

Terima kasih ShadowRanger, Mr. Xcoder, dan Daffy! @ShadowRanger Saya harus tetap dengan i[c:]karena cara yang lebih pendek menyebabkan masalah off-by-one yang aneh untuk beberapa input kasus sudut (coba letakkan |tepat di tengah - di atas bilah).
veganaiZe

1

PHP, 105 byte

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

mencetak -1/ 0/ 1untuk kiri / keseimbangan / kanan. Jalankan sebagai pipa dengan -nRatau coba online .

kerusakan

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

Arang , 31 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Output 0 untuk saldo atau -1 atau 1 untuk jatuh ke kiri atau kanan. Sunting: Perubahan dalam Arang sekarang berarti itu ≔ΣEθ×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰berfungsi selama 24 byte: Cobalah secara online! Tautan adalah untuk mengucapkan versi kode. Catatan: Kedua jawaban memerlukan input empuk, tetapi dapat diadaptasi untuk menerima input tidak empuk dengan biaya 3 byte: ≔⁰ξFLη≔⁺ξ×⁻ι⌕ζ|⁻℅§◨θLηι³¹ξI⁻›ξ⁰‹ξ⁰ Coba online! ≔ΣE◨θLη×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰ Cobalah online! Tautan adalah untuk mengucapkan versi kode.


Anda mungkin ingin menyebutkan ini, berharap baris input diisi dengan panjang yang benar dengan spasi, sehingga input yang tidak diadili mungkin tidak berfungsi.
FlipTack

@FlipTack Lebih baik lagi, saya telah menemukan versi yang menerima input yang tidak ditambahkan.
Neil
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.