Я опрокинусь?


36

обзор

Учитывая 3 строки строки, выясните, если структура падает влево, уравновешивает или падает вправо.

Структура ввода

Вы можете представить конструкцию в виде металлического стержня с наполнителем сверху, который сбалансирован сверху вертикального стержня.

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

Первая строка - это предметы. Вес каждого предмета рассчитывается как значение ascii символа минус 32. (Символы до 32 не учитываются, а пробелы весят 0). Имейте в виду, что сила предмета на стержне равна его весу, умноженному на расстояние до точки поворота.

Вторая строка - это удочка. Каждая длина стержня весит 1 единицу. Эта строка исключительно равна знакам ( =).

Третья линия - это точка разворота. Это может быть помещено где угодно, и представлено числом пробелов, сопровождаемых единственным |символом pipe ( ).

Примеры

Входные данные:

=====
  |

Выход: баланс

Входные данные:

=====
   |

Выход: падает слева

Входные данные:

    %
=====
   |

Вывод: баланс (потому что %весит достаточно, чтобы противодействовать весу левой стороны стержня)

Входные данные:

 аа
=======
   |

Вывод: падает вправо (потому что aсправа находится дальше от точки поворота)

Входные данные:

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

Выход: падает слева

Входные данные:

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

Вывод: падает справа (строчные буквы тяжелые!)

Входные данные:

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

Выход: баланс

Заметки

  • Конечный пробел разрешен, ведущий пробел - нет.
  • Ваша программа может выводить в любом формате, который вам нравится, при условии, что есть 3 различных выхода для left, balance и Right.
  • Ваша программа должна принять формат, показанный как ввод.


Может ли программа взять три строки как три отдельные строки (например, как три аргумента функции или как список из трех элементов)?
notjagan

@notjagan Входные данные должны быть одной строкой, разделенной символами новой строки.
Даффи

Связанный , возможно, дурак.
xnor

@xnor Не дурак, потому что этот вопрос касается только заглавных букв, и его цель - найти точку опоры. У меня вопрос обо всех символах ascii> = 32, и мой задает опору и спрашивает, не упадет ли структура. По сути, обратный тому, который вы связали.
Даффи

Ответы:


8

JavaScript (ES6), 116 111 108 106 байт

-5 байтов путем суммирования через eval(array.join`+`)вместо array.reduce().
-3 байта по умолчанию 1вместо 32 - 31, позволяя удалить скобки.
-2 байта, поскольку точка разворота - длина последней строки - 1

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

Выходы -1, 0или 1, для левого, сбалансированного или правого соответственно. Закончилось тем же, что и ответ Питона на Chas Brown , так что заслуга в этом.

Может сохранить 4 байта, если первая строка дополняется, чтобы соответствовать длине стержня с помощью
(31-t.charCodeAt(i))*(b.length+~i).

Тестовый фрагмент

Включает дополнительный вывод ( Left/ Balanced/ Right) вместе с номером.

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>

Еще один 106-байтовый метод

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

Вместо того , чтобы создавать joinмассив на +s, мы создаем строку чисел, каждое с префиксом +. Ведущий +игнорируется.


1
Я думаю, (b.length+~i)может помочь сохранить байт. (Также я не понимаю, почему у вас есть ||1.)
Нейл

1
@Neil b.length+~iвозвращает отрицательное значение i-b.length+1; это могло бы помочь, если бы я мог отрицать другую часть. Что касается того ||1, что это было, потому что я предполагал, что первая строка не была дополнена, чтобы соответствовать длине стержня, поэтому t.charCodeAt(i)вернулась бы NaNза конец первой строки.
Джастин Маринер

Я не должен был попробовать тестовый случай без дополнения; спасибо за объяснение.
Нил

3

Python 2 , 112 110 байт

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)

Попробуйте онлайн!

РЕДАКТИРОВАТЬ: Наконец-то удалось устранить enumerateи rjustдля 2 жалких байтов ... Мех!

Берет в строку; выводит -1,0 или 1 для падений влево, остатков, падений вправо соответственно.

Первый проход на 112 байт был:

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)Мне потребовалось некоторое время, чтобы понять, что это фактически включает вес самого стержня вместе с предметами. Очень умно!
Даффи

1
Согласно мета , вы можете заменить returnс printна -1 байт (хотя это не очень приятно играть с текущим кодом TIO).
notjagan

3

Haskell, 212 171 байт (188, если принять входные данные одной строкой)

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)

171 байтовый вариант

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

Вариант 188 байт

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

объяснение

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
Вы можете использовать fromEnumвместо ordи бросить import. cможет быть упрощен до c p=max(ord p-32)0(или с fromEnum) и, поскольку вы используете его только один раз, вставьте его.
Nimi

Или вы можете добавить (Lambdabot) к вашему названию, это импортирует почти все, что вам нужно, смотрите здесь .
მოიმო

1
Функция cможет быть даже упрощена (символы до 32 не рассматриваются) в дальнейшем c p=ord p-32. Также pв основном length(минус 1), так p x=length x-1что будет работать (и вы можете включить его тоже). Также посмотрите на мое решение, как я использую signum- вы могли бы сделать, r o l s = signum $ 2 * z ...что возвращает 0,1,-1для B, L, R.
მოიმო

1
Кроме того, это решение, по-видимому, не [3,4,7]проходит тестовые случаи и принимает 3 строки вместо одной. (см. lines)
მოიმო

1
Вот версия с несколькими советами (экономит 29 байт;)).
მოიმო

2

Желе , 30 байт

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

Тестирование

Выходы 0 для сбалансированного, 1 для правого и -1 для левого.

Как это работает

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

Желе , 24 байта

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

Попробуйте онлайн!

-1для падения влево, 0для балансировки, 1для падения вправо (полная программа).
[-1]для падения влево, [0]для балансировки, [1]для падения вправо (функция).

Первая строка должна иметь конечные пробелы, последняя строка не должна.

Пояснение (мы начинаем с нижней строки):

Прежде всего, мы работаем с отдельными строками, поэтому нам нужно как-то их получить. Это работа для . Затем нам нужно обработать \nверсию ввода -split так, как если бы это был исходный ввод, поэтому мы используем µмонадическую цепочку, примененную к текущему значению.

Теперь мы начинаем настоящую работу, и нашей первой работой будет вычисление коэффициентов весов. По сути, это диапазон [расстояние от крайнего левого до центра. 0 .. расстояние от центра до крайнего справа]. Прежде всего, мы должны найти основанный на 1 индекс пивота, который по сути является длиной последней строки без конечных пробелов. Таким образом, мы извлекаем последнюю строку (линию разворота) из нашего исходного списка , поскольку она нам больше не нужна, а затем мы берем ее длину L. Затем нам нужно взять длину стержня, для которой мы делаем то же самое с последней последней строкой (линия стержня) с ṪL$. Наконец, чтобы получить диапазон, мы наносим на карту | х - у | в [1..rod length], где x - это индекс поворота, а yкаждый элемент списка, на который мы наносим карту. Мы делаем это, используя ạЀ, где вычисляет | х - у | и Ѐсоставляет от 1 до и включая длину стержня. Теперь у нас будет диапазон, который мы хотим.

После этого мы должны умножить каждое целое число, представляющее кусок стержня, на соответствующий вес. Для вычисления весов мы используем Çпереход к верхней строке нашего кода. Мы берем на себя оставшуюся линию , ее charcodes с O, а затем вычислить й - 31 с использованием _31, й не каждый charcode. Затем мы присваиваем пробелу вес 1 (0 + штанга = 1), !вес 2 (1 + 1) и т. Д. Мы закончили с верхней строкой, поэтому теперь Çвернемся список весов, который мы умножим на соответствующий целые числа, представляющие части стержня с ×.

После этого мы разделяемся с ṣ0точкой поворота, представленной 0 (поскольку любой вес там не повлияет на результат), в результате получается список в форме [[1-й вес, 2-й вес ... вес перед поворотом] , [вес после разворота, вес после того, что перед… последним весом]]. Эти списки представляют стороны стержня слева и справа. Теперь мы суммируем каждый из списков, используя S€для получения суммарных весов с каждой стороны, и используем, Iчтобы взять дельту, которая будет отрицательной, если левая сторона тяжелее, нулями, если они равны весу, и положительной, если правая сторона тяжелее. , Таким образом, чтобы вернуть конечный результат, используя его должным образом, мы берем знак с .


2

APL (Dyalog) , 43 байта *

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

Попробуйте онлайн!

⊆⊢ разделить аргумент на серии символов, которые

⎕TC[2]∘≠ отличается от 2 - го T erminal C ontrol характера (Linefeed) **

{} Применить следующую анонимную функцию в списке строк:

⊃⌽⍵ в первой строке перевернутого списка (т.е. в последнем)

'|'⍳⍨ найти индекс точки поворота

()- Вычтите это из следующего списка:

  ⊃⍵ первая строка

   его длина

   все ɩ ndices о том , что

()+.× Взвешенная сумма с этими весами и следующими значениями:

  ⊃⍵ первая строка

  ⎕UCS Точки код в U niversal С haracter S и др

  ¯31+ добавить отрицательный тридцать один (32 для требуемого смещения минус один для стержня)

× знак того


* Для 1 байта на символ используйте {×(¯31+⎕UCS↑⍵)+.×(⍳≢↑⍵)-'|'⍳⍨↑⌽⍵}⎕TC[3]∘≠⊂⊢с ⎕ML←3. Попробуйте онлайн!
** ⎕TCустарела и используется здесь только для целей игры в гольф. В производственном коде нужно использовать ⎕UCS 10.


2

Haskell (Lambdabot), 142 байта

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

Попробуйте онлайн!

Безголовая версия:

-- 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 байт

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

Ожидает, что входные строки будут дополнены (с пробелами) правильной длины. Выходы -1для падений влево , 0для сбалансированных и 1для падений вправо .

Попробуйте онлайн!


94 байта

Для +4 байтов у нас может быть версия, которая, используя whileцикл, требует зачеркнутых строк, а не дополненных строк:

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)

Попробуйте онлайн!


1

Рубин, 543 байта

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
Добро пожаловать в PPCG! : D Задача задач в код-гольфе - сделать ваш код как можно меньше. Вы можете уменьшить размер кода, сделав все переменные и имена функций одним символом и удалив пробелы, где это возможно.
Даффи

1

C (gcc) , 106107 121 123 124 129 131 байтов

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

Верните 0 для падения влево, 1 для баланса и 2 для падения вправо.

Требуется, чтобы все три строки имели одинаковую длину и заканчивались \nдля определения длины строки.

Попробуйте онлайн!


1

Математика, 91 92 байтов

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

Первая строка должна иметь одинаковую длину со стержнем. Третья строка не должна содержать пробелов.

Верните -1, 0, 1 для падения влево, баланса и падения вправо.


1

C # (.NET Core) , 127 95 90 + 18 = 108 байтов

Для этой функции первая строка должна быть дополнена справа пробелами такой же длины, что и стержень, а третья строка не должна иметь пробельных пробелов. Эти условия разрешены (см. Комментарии к вопросу).

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

Попробуйте онлайн!

Выходы:

-1 для наконечника влево
0 для баланса
1 для наконечника вправо


1

Python 3, 217 байт

Также работает в 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)

Возвращает 1 для левой стороны, -1 для правой стороны или ноль, если сбалансирован.

Читаемая версия:

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
Вам не нужно sum([...]), вы можете просто иметьsum(...)
г-н Xcoder

@ Убедитесь, что это должно быть на 100% совместимо с вашей спецификацией и всеми приведенными примерами входных данных. Если вы согласны, пожалуйста, дайте мне знать, чтобы я мог оптимизировать его. Спасибо.
veganaiZe

@veganaiZe прошел все мои тесты, выглядит хорошо! :)
Даффи

1
Вещи, чтобы сократить его: i[c:].find(e)можно i.find(e,c), использовать i,m,n=s.split('\n')и sвообще избегать необходимости , использовать return 2*(r>l) or l>rдля значительного сокращения затрат на тестирование в конце (возвращаемое значение численно эквивалентно, но Trueвместо 1и Falseвместо 0), или действительно использовать другой набор возвращаемых значений значения и сделать, return (l>r)-(r>l)чтобы вернуть 1, 0 или -1, как это cmpделала старая функция.
ShadowRanger

Спасибо ShadowRanger, мистер Xcoder и Даффи! @ShadowRanger Я должен был придерживаться, i[c:]потому что более короткий путь вызвал странную проблему с одним-единственным вводом в угловом регистре (попробуйте разместить |точно посередине - над полосой).
veganaiZe

1

PHP, 105 байт

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

печатает -1/ 0/ 1влево / баланс / вправо. Запустите как трубу с -nRили попробуйте онлайн .

сломать

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

Древесный уголь , 31 байт

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

Попробуйте онлайн! Ссылка на подробную версию кода. Выходы 0 для баланса или -1 или 1 для падения влево или вправо. Изменить: Изменения в Charcoal теперь означают, что ≔ΣEθ×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰работает на 24 байта: попробуйте онлайн! Ссылка на подробную версию кода. Примечание. Оба ответа требуют ввода с дополнением, но могут быть адаптированы для приема ввода без дополнения со стоимостью 3 байта: ≔⁰ξFLη≔⁺ξ×⁻ι⌕ζ|⁻℅§◨θLηι³¹ξI⁻›ξ⁰‹ξ⁰ попробуйте онлайн! ≔ΣE◨θLη×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰ Попробуйте онлайн! Ссылки на подробную версию кода.


Вы можете упомянуть об этом, так как ожидается, что строки ввода будут дополнены правильной длиной с пробелами, поэтому незаполненный ввод может не работать.
FlipTack

@FlipTack Еще лучше, я разработал версии, которые принимают ввод без ввода.
Нил
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.