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


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.