Определить «удачу» струны


35

Если дана строка, верните ее «удачу».

Удача строки, как я только что придумал для этой задачи, является целым числом, определяемым так:

  • Базовое везение для строки - 1.
  • Для каждой последовательной буквы, которую она разделяет со словом «lucky» (без учета регистра), умножьте удачу на 2. Например, если ваша строка была « lu mberjack» или «sma ck », вы умножили бы на 4. (Более конкретно, 2 ^ количество последовательных символов.)
    • Совместно используемые буквы должны быть в том же порядке, в котором они указаны как «счастливые», но могут начинаться в любом месте слова с тем же значением («luc» имеет тот же множитель 8 *, что и «cky»).
    • Если слово встречается несколько раз, когда оно разделяет последовательные символы на счастливое, используйте самую длинную последовательную строку символов.
  • Для ЛЮБОГО письма оно делится со словом «предзнаменование», отнимает 2 от удачи.
    • Он может соответствовать персонажу любое количество раз и в любом порядке. Например, строка «nnnnnomemenn» теряет 24 удачи (12 совпадающих букв)

Пример:

luck("lucky")
>>32

2 ^ 5 (5 последовательных букв) = 32

luck("firetruck")
>>6

2 ^ 3 - 2 (3 последовательных письма от uck , e разделены с предзнаменованием)

luck("memes")
>>-7

1 - 8 (базовая сумма, 4 делятся на «предзнаменование»)

Это код гольф, поэтому ответ с наименьшим количеством байтов выигрывает.

Вы можете вводить и выводить данные любым способом - написать функцию, использовать стандартный ввод и т. Д.

Для функций предположите, какой тип данных будет иметь смысл для этого языка. (Например, в JavaScript вам нужно передать a Stringи вернуть a Number)

Изменить: Вы можете предположить, что любой ввод в нижнем регистре.


8
Хороший первый вызов!
Алекс А.

2
Должна ли программа принимать ввод заглавными буквами?
Busukxuan

2
@busukxuan Хороший вопрос - нет, он не должен принимать ввод в верхнем регистре.
Обугленная

@ Cat Не уверен, что я вполне понимаю, о чем вы спрашиваете. Но вы можете просто предположить, что весь ввод будет строчным, и вам не нужно перехватывать ввод заглавными буквами.
Charredgrass

1
Можем ли мы принять верхнюю или нижнюю границу удачи данного входа? то есть, какое наименьшее количество бит / тип данных я могу выбрать, или оно настолько велико, насколько может справиться мой язык? то есть, так int8_t str_luck(const char* str);и должно быть uint64_t str_luck(const char* str);?
кот

Ответы:


7

05AB1E , 36 32 28 26 байт

Œv'¸éyåiyˆ}}¯é¤go¹'ƒÖ¦Ãg·-

объяснение

Œv         }                  # for each substring of input
  '¸éyåi  }                   # if substring is part of "lucky"
        yˆ                    # add it to global array
            ¯é¤               # get the longest such substring
               go             # raise 2 to its length
                 ¹'ƒÖ¦Ã       # remove all chars from input that isn't in "omen"
                       g·     # get length and multiply by 2
                         -    # subtract
                              # implicitly display

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

Сохранено 2 байта благодаря Аднану


Сжатие для 1 слова также может быть сделано с ', так что для 26: Œv'¸éyåiyˆ}}¯é¤go¹'ƒÖ¦Ãg·-:).
Аднан

@Adnan: странно. Я был уверен, что попробовал это. Очевидно нет. Благодарность!
Эминья

почему это не лучший ответ?
noɥʇʎԀʎzɐɹƆ

7

JavaScript (ES7), 123 112 107 байт

s=>2**[5,4,3,2,1,0].find((i,_,a)=>a.some(j=>s.includes("luckyL".substr(j,i))))-2*~-s.split(/[omen]/).length

Редактировать: Сохранено 11 байтов благодаря @Titus, предполагая, что буква Lне появляется на входе. Сохранено 5 байтов благодаря @Oriol. Версия ES6 для 125 114 109 байтов:

f=
s=>(1<<[5,4,3,2,1,0].find((i,_,a)=>a.some(j=>s.includes("luckyL".substr(j,i)))))-2*~-s.split(/[omen]/).length
;
<input oninput=o.textContent=f(this.value)><pre id=o></pre>


Почему вы используете replace([^])вместо match([])? Вы тратите 3 байта или есть причина?
Тит

@Titus Сколько байтов стоит, чтобы иметь дело с результатом nullсовпадения?
Нил

1
Четыре для строки, и пара ()в этом случае; съедая все шесть, что вы бы сэкономить match(/[omen]/). Жалость.
Тит

1
@Titus Не уверен, что это то, что вы имели в виду, но добавив Lв конец substr (который никогда не появится в исходной строке) мне не нужно беспокоиться о посторонних совпадениях, и я могу фактически использовать один и тот же массив [5,4,3,2,1,0]оба раза, экономя колоссальные 13 байтов!
Нил

1
-2*s.split(/[omen]/).length+2короче
Ориол

6

Pyth, 27 26 28 байтов

-^2le+k}#"lucky".:Q)yl@"omen

1 байт сохранен благодаря OP :-)

Объяснение:

                                 Implicit Q as input
                .:Q              Find all substrings of input
     +k}#"lucky"                 Filter for substring of "lucky", prepend "" in case of []
    e                            Take last element, which is longest
   l                             Get its length
 ^2                              Raise two to that
                      @"omen"Q   Filter Q for characters in "omen"
                     l           Get length; counts how many characters in "omen" there are
                    y            Double that
-                                Find the difference

Проверьте это здесь .


1
Я не эксперт в Pyth, но я верю, что вы можете перейти "omen"на справедливость, "omenи
Pyth

@charredgrass Ой, моя ошибка :-)
busukxuan

1
Кажется, не работает для строки без символов в ней "повезло". "мемы", например.
Emigna

1
@ Emigna Ах. опять нулевой случай .... Спасибо, исправили!
Busukxuan

6

Рубин, 91 87 байт

String#countВнушительное использование снова поражает! (Когда передается строка, она считает все вхождения каждой буквы в аргументе функции вместо всех вхождений всей строки.)

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

->s{2**(z=0..5).max_by{|j|z.map{|i|s[b="lucky"[i,j]]?b.size: 0}.max}-2*s.count("omen")}

Версия, которая берет строки из STDIN и печатает их: 89 байтов (86 +3 от -nфлага)

p 2**(z=0..5).max_by{|j|z.map{|i|$_[b="lucky"[i,j]]?b.size: 0}.max}-2*$_.count("omen")

1
._. это String#countстранно +1 за (ab) его использование. Кроме того, это короче, чтобы использовать, getsа не функцию?
Вниз

1
@ Downgoat, если я getsI также должен putsдля вывода, так что не в этом случае.
Чернила стоимости

4

Рубин: 100 байт

->s{2**(m=0;4.times{|j|1.upto(5){|i|m=[i,m].max if s.match"lucky"[j,i]}};m)-s.scan(/[omen]/).size*2}

Попробуйте использовать это /[omen]/как регулярное выражение - он будет соответствовать любому персонажу и лучше в практическом использовании, чем цепочка |s для отдельных персонажей.
Charredgrass

3

JavaScript - 206 байт

r=>{var a="lucky";r:for(var e=5;e>0;e--)for(var n=0;6>n+e;n++){var o=a.substring(n,e+n);if(r.includes(o))break r}for(var t=0,e=0;e<r.length;e++)('omen'.indexOf(r[e])+1)&&t++;return Math.pow(2,o.length)-2*t}

1
Вы можете изменить это условие: s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n'выглядеть так:"oman".split("").includes(s[k])
addison

1
Добро пожаловать в PPCG! Вы можете уменьшить это, убрав пробелы для сохранения байтов. Кроме того, вместо (s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n')вас можно использовать ('omen'.indexOf(s[k])+1)(при условии, что это JavaScript)
charredgrass

Спасибо за советы! Дошел до 237, хотя похоже, что толпа Руби меня побила.
Кристофер Бургдорф

Еще одна небольшая вещь: вы можете сделать сокращение function luck(r), чтобы r=>просто сделать его анонимной функцией, это все, что необходимо для этой задачи. Кроме того, я внес изменения в задачу, чтобы вам не приходилось беспокоиться о деле, чтобы вы могли удалитьr=r.toLowerCase();
charredgrass

Вместо того, чтобы substringвы могли использовать, sliceя верю (проверьте это, хотя, поскольку я не уверен)
Downgoat

3

Рубин, 57 байт

b=gets.count'omen'
$.+=1while/[lucky]{#$.}/
p 2**$./2-2*b

getsустанавливает $.значение 1 как побочный эффект, затем мы увеличиваем его до тех пор, пока регулярное выражение, совпадающее с $.последовательными счастливыми символами, больше не будет совпадать.


3

Хаскелл, 99

Другой подход ... Я только что узнал о псевдонимах функций

import Data.List
s=subsequences
i=intersect
l=length
f n=2^(l$last$i(s"lucky")$s n)-2*l(i n$"omen")

использование

f"lucky"
32

f"firetruck"
6

f"memes"
-7

2

Mathematica, 86 байт

Код:

2^StringLength@LongestCommonSubsequence[#,"lucky"]-2StringCount[#,{"o","m","e","n"}]&

Объяснение:

LongestCommonSubsequenceвозвращает самую длинную непрерывную подстроку, общую для ввода и "lucky". StringLengthдает свою длину. StringCountподсчитывает количество появлений символов "omen"на входе.


2

Python (139 байт)

import itertools as t
s=input()
print 2**max([j-i for i,j in t.combinations(range(6),2)if'lucky'[i:j]in s]+[0])-2*sum(_ in'omen'for _ in s)

Вы можете сохранить один байт, используяfrom intertools import*
wnnmaw

1

TSQL, 233 байта

Golfed:

DECLARE @t varchar(99)='oluck'

,@z INT=0,@a INT=0,@ INT=1,@c INT=0WHILE @a<LEN(@t)SELECT
@a+=IIF(@=1,1,0),@z=IIF('LUCKY'LIKE'%'+x+'%'and @>@z,@,@z),@c+=IIF(x
IN('O','M','E','N'),2,0),@=IIF(@+@a-1=LEN(@t),1,@+1)FROM(SELECT
SUBSTRING(@t,@a,@)x)x PRINT POWER(2,@z)-@c

Ungolfed:

DECLARE @t varchar(99)='oluck'

,@z INT=0
,@a INT=0
,@  INT=1
,@c INT=0
WHILE @a<LEN(@t)
  SELECT
    @a+=IIF(@=1,1,0),
    @z=IIF('LUCKY'LIKE'%'+x+'%'and @>@z,@,@z),
    @c+=IIF(x IN('O','M','E','N'),2,0),
    @=IIF(@+@a-1=LEN(@t),1,@+1)
    FROM(SELECT SUBSTRING(@t,@a,@)x)x
PRINT POWER(2,@z)-@c

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


1

Haskell ( 134 132 байта)

import Data.List
c[]=[]
c s@(_:x)=inits s++c x
l=length
g q=2^(maximum$map(\z->l q-l(q\\z))$c"lucky")-2*(l$intersect q"omen")

Не гольфист кода и не программист на Haskell, поэтому хотелось бы получить несколько советов по этому вопросу.

(Пример: g "firetruck")


Я не являюсь экспертом по Haskell, но мне удалось выделить несколько байсов, слегка изменив алгоритм и используя псевдонимы функций для повторно используемых функций.
Зилвий

1

Python 3, 168 157 152 139 144 136 байтов

РЕДАКТИРОВАТЬ: действительно очевидные вещи, которые я должен был видеть проще, были изменены, а некоторые немного менее очевидными.

Изменить 2: сутулость (˚n˚). Программа выкинула ошибки. Я исправил это. на самом деле не 153 :(

Спасибо Leaky Nun за сохранение 5 байт и jmilloy за сохранение 13 8 байт.

s=input()
p=q=k=len(s)
m=0
while-~p:
 while-~q:m=(m,q-p)[(s[p:q]in"lucky")*q-p>m];q-=1
 p-=1;q=k
print(2**m-2*sum(i in"omen"for i in s))

Программа просматривает все возможные подстроки на входе (возможно, потому что она также вычисляет невозможные подстроки, например, от 8 до 7), проверяет, находится ли подстрока в «счастливом», затем устанавливает показатель степени 2 равным длине подстрока должна быть больше текущего значения. Возможно, можно улучшить, используя только один цикл while. Возможно, можно использовать некоторые улучшения; Я все еще изучаю это.


while p+1становитсяwhile-~p
Leaky Nun

так как b=s[p:q], len(b)должен быть q-pправ?
Дрянная Монахиня

Я украл у вас метод ввода и печати, но сделал все остальное совсем иначе, спасибо! Я думаю, что если вы просто сделаете print(2**m-2*sum(i in"omen" for i in s))последние три строчки, вы сделаете лучше, например, 148?
Jmilloy

О, и вы можете просто переместить s [p: q] в условие if while-~q:n=q-p;m=n if(s[p:q]in"lucky")*n>m else m;q-=1для 143?
Jmilloy

sum(map(s.count,"omen"))сохраняет один байт, делая его 135
Black Owl Кай

1

PHP программа, 139 135 108 байт

квантовый скачок не удался для нескольких подстрок, где первый случай короче. :(

на самом деле я мог бы сохранить еще 7 байтов в PHP <5.4 с register_globals на

<?for($s=$argv[1];$i<5;$i++)for($j=6;--$j;)$r=max($r,strstr($s,substr('lucky*',$i,$j))?2**$j:1);echo$r-2*preg_match_all('/[omen]/',$s);

использование: php -d error_reporting=0 <filename> <string>

+5 за функцию:

function f($s){for(;$i<5;$i++)for($j=6;--$j;)$r=max($r,strstr($s,substr('lucky*',$i,$j))?2**$j:1);return$r-2*preg_match_all('/[omen]/',$s);}

тесты (по функции)

echo '<table border=1><tr><th>input</th><th>output</th><th>expected</th><th>ok?</th></tr>';
foreach([
    'lumberjack'=>0,        'smack'=>2,
    'nnnnnomemenn'=>-23,    'lucky'=>32,
    'omen'=>-7,             'firetruck'=>6,
    'memes'=>-7,            'determine the “luck” of a string'=>0,
    'amazing'=>-3,          'wicked'=>2,
    'chucky'=>16,           'uckyuke'=>14,
    'ugly'=>2,              'lucy'=>8,
    'lukelucky'=>30
] as $x=>$e){
    $y=f($x);
    echo"$h<tr><td>",$x,'</td><td>',$y,'</td><td>',$e,'</td><td>',$e==$y?'Y':'N',"</td></tr>";
}echo '</table>';


0

Скала, 155 байт

def f(w:String)=(1::List.fill((for(a<-1 to 5;s<-"lucky".sliding(a))yield if(w.contains(s)) a else 0).max){2}).product-2*w.filter("omen".contains(_)).length
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.