Xác định số điểm may mắn của một chuỗi


35

Đưa ra một chuỗi, trả lại "may mắn" của chuỗi đó.

May mắn của một chuỗi, vì tôi hoàn toàn chỉ bù cho mục đích của thử thách này, là một số nguyên, được xác định như vậy:

  • Cơ sở may mắn cho một chuỗi là 1.
  • Đối với mỗi chữ cái liên tiếp, nó chia sẻ với từ "may mắn" (không phân biệt chữ hoa chữ thường), nhân số may mắn lên 2. Ví dụ: nếu chuỗi của bạn là " lu mberjack" hoặc "sma ck " bạn sẽ nhân với 4. (Cụ thể hơn, 2 ^ số ký tự liên tiếp được chia sẻ.)
    • Các chữ cái được chia sẻ phải theo thứ tự liên tiếp xuất hiện trong "may mắn" nhưng có thể bắt đầu ở bất cứ đâu trong từ có cùng giá trị ("luc" có cùng số nhân 8 * với "cky").
    • Nếu từ có nhiều lần xuất hiện trong đó nó chia sẻ các ký tự liên tiếp với may mắn, hãy sử dụng chuỗi ký tự liên tiếp dài nhất.
  • Đối với BẤT K letter chữ cái nào nó chia sẻ với từ "điềm báo" trừ đi 2 từ may mắn.
    • Nó có thể phù hợp với một nhân vật bất kỳ số lần, theo bất kỳ thứ tự nào. Chẳng hạn, chuỗi "nnnnnomemenn" mất 24 may mắn (12 chữ cái khớp)

Thí dụ:

luck("lucky")
>>32

2 ^ 5 (5 chữ cái liên tiếp) = 32

luck("firetruck")
>>6

2 ^ 3 - 2 (3 chữ cái liên tiếp từ uck , e chia sẻ với điềm báo)

luck("memes")
>>-7

1 - 8 (số tiền gốc, 4 được chia sẻ với "điềm báo")

Đây là mã golf, vì vậy câu trả lời có ít byte nhất sẽ thắng.

Bạn có thể nhập và xuất bất kỳ cách nào bạn muốn - viết một hàm, sử dụng đầu vào tiêu chuẩn, v.v.

Đối với các hàm, giả sử bất kỳ loại dữ liệu nào sẽ có ý nghĩa đối với ngôn ngữ đó. (Ví dụ: trong JavaScript, bạn sẽ được thông qua Stringvà trả lại a Number)

Chỉnh sửa: Bạn có thể giả sử bất kỳ đầu vào là chữ thường.


8
Thử thách đầu tiên tốt đẹp!
Alex A.

2
Chương trình có nên chấp nhận đầu vào chữ hoa?
busukxuan

2
@busukxuan Câu hỏi hay - không, không cần chấp nhận đầu vào chữ hoa.
charredgrass

@cat Không chắc tôi khá hiểu những gì bạn đang hỏi. Nhưng bạn chỉ có thể giả sử tất cả đầu vào sẽ là chữ thường và bạn không cần phải bắt bất kỳ đầu vào chữ hoa nào.
charredgrass

1
Chúng ta có thể giả định giới hạn trên hoặc dưới về sự may mắn của một đầu vào nhất định không? tức là số bit / loại dữ liệu nhỏ nhất mà tôi có thể thoát khỏi, hoặc nó có lớn như ngôn ngữ của tôi có thể xử lý không? đó là, nó nên int8_t str_luck(const char* str);hay nên uint64_t str_luck(const char* str);?
con mèo

Câu trả lời:


7

05AB1E , 36 32 28 26 byte

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

Giải trình

Œ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

Dùng thử trực tuyến

Đã lưu 2 byte nhờ Adnan


Nén cho 1 từ cũng có thể được thực hiện với ', vì vậy trong 26: Œv'¸éyåiyˆ}}¯é¤go¹'ƒÖ¦Ãg·-:).
Ad Nam

@Ad Nam: Lạ. Tôi chắc chắn tôi đã thử nó. Rõ ràng là không. Cảm ơn!
Emigna

Tại sao đây không phải là câu trả lời hàng đầu?
noɥʇʎԀʎzɐɹƆ

7

JavaScript (ES7), 123 112 107 byte

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

Chỉnh sửa: Đã lưu 11 byte nhờ @Titus bằng cách giả sử rằng chữ cái Lkhông xuất hiện trong đầu vào. Đã lưu 5 byte nhờ @Oriol. Phiên bản ES6 cho 125 114 109 byte:

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>


Tại sao bạn sử dụng replace([^])thay vì match([])? Bạn có lãng phí 3 byte hoặc có một lý do?
Tít

@Titus Mất bao nhiêu byte để xử lý nullkết quả khớp?
Neil

1
Bốn cho một chuỗi, và một cặp ()trong trường hợp này; ăn hết sáu cái mà bạn sẽ tiết kiệm được match(/[omen]/). Lòng thương hại.
Tít

1
@Titus Không chắc đó có phải là ý của bạn không nhưng bằng cách thêm Lvào phần cuối của chuỗi (sẽ không bao giờ xuất hiện trong chuỗi gốc) Tôi không phải lo lắng về kết quả trùng khớp và tôi thực sự có thể sử dụng cùng một mảng [5,4,3,2,1,0]cả hai lần, tiết kiệm được 13 byte!
Neil

1
-2*s.split(/[omen]/).length+2ngắn hơn
Oriol

6

Bình thường, 27 26 28 byte

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

Lưu 1 byte nhờ OP :-)

Giải trình:

                                 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

Kiểm tra nó ở đây .


1
Tôi không phải là chuyên gia về Pyth nhưng tôi tin rằng bạn có thể thay đổi "omen"thành chỉ "omenvà Pyth sẽ hiểu
charredgrass

@charredgrass Rất tiếc, lỗi của tôi :-)
busukxuan

1
Dường như không hoạt động cho chuỗi mà không có ký tự "may mắn" trong đó. "Memes" chẳng hạn.
Emigna

1
@Emigna À. trường hợp không một lần nữa .... Cảm ơn, đã sửa nó!
busukxuan

6

Ruby, 91 87 byte

String#countViệc sử dụng tài chính một lần nữa đình công! (Khi được thông qua một Chuỗi, nó sẽ đếm tất cả các lần xuất hiện của mỗi chữ cái trong đối số hàm thay vì tất cả các lần xuất hiện của toàn bộ chuỗi.)

Dùng thử trực tuyến

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

Một phiên bản lấy các dòng từ STDIN và in chúng: 89 byte (86 +3 từ -ncờ)

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

1
._. đó String#countlà lạ +1 cho (ab) sử dụng nó. Cũng là nó ngắn hơn để sử dụng getschứ không phải là một chức năng?
Hạ cấp

1
@Downgoat nếu tôi getscũng phải putscho đầu ra, vì vậy không phải trong trường hợp này.
Mực giá trị

4

Ruby: 100 byte

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

Hãy thử /[omen]/làm regex để đánh golf xuống - nó sẽ phù hợp với bất kỳ nhân vật nào và sử dụng thực tế tốt hơn so với chuỗi |cho các nhân vật đơn lẻ.
charredgrass

3

Javascript - 206 byte

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
Bạn có thể thay đổi điều kiện này: s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n'để trông như thế này:"oman".split("").includes(s[k])
addison

1
Chào mừng đến với PPCG! Bạn có thể đánh gôn xuống bằng cách xóa khoảng trắng để bảo tồn byte. Ngoài ra, thay vì (s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n')bạn có thể sử dụng ('omen'.indexOf(s[k])+1)(giả sử đây là JavaScript)
charredgrass

Cảm ơn vì những lời khuyên! Giảm xuống còn 237, mặc dù có vẻ như đám đông Ruby đã đánh bại tôi.
Christopher Burgdorff

Một điều nhỏ khác: bạn có thể viết tắt function luck(r)để r=>biến nó thành một chức năng ẩn danh, đó là tất cả những gì cần thiết cho thử thách này. Ngoài ra tôi đã thực hiện một chỉnh sửa cho thử thách để bạn không phải lo lắng về trường hợp để bạn có thể xóar=r.toLowerCase();
charredgrass

Thay vì substringbạn có thể sử dụng slicetôi tin (mặc dù vậy, hãy kiểm tra điều này, vì tôi không chắc chắn)
Downgoat

3

Ruby, 57 byte

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

getsđặt $.thành 1 làm hiệu ứng phụ, sau đó chúng tôi tăng nó cho đến khi biểu thức chính quy khớp với các $.ký tự may mắn liên tiếp không còn phù hợp.


3

Haskell, 99

Một cách tiếp cận khác ... Tôi vừa tìm hiểu về hàm răng cưa

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

Sử dụng

f"lucky"
32

f"firetruck"
6

f"memes"
-7

2

Toán học, 86 byte

Mã số:

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

Giải trình:

LongestCommonSubsequencetrả về chuỗi con liền kề dài nhất phổ biến cho đầu vào và "lucky". StringLengthcho chiều dài của nó. StringCountđếm số lần xuất hiện của các ký tự "omen"trong đầu vào.


2

Con trăn (139 byte)

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)

Bạn có thể lưu một byte bằng cách sử dụngfrom intertools import*
wnnmaw

1

TSQL, 233 byte

Chơi gôn

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

Ung dung:

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

Dùng thử trực tuyến


1

Haskell ( 134 132 byte)

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")

Không phải là một tay golf mã cũng không phải là lập trình viên Haskell, vì vậy sẽ thích một số mẹo về cái này.

(Ví dụ g "firetruck":)


Tôi cũng không phải là Chuyên gia của Haskell, nhưng đã cố gắng khắc chế một vài điều tạm biệt bằng cách thay đổi thuật toán một chút và sử dụng các bí danh hàm trên các hàm được sử dụng lại.
Zylviij

1

Trăn 3, 168 157 152 139 144 136 byte

EDIT: Những điều thực sự rõ ràng tôi nên thấy dễ dàng hơn đã được thay đổi, và một số ít rõ ràng hơn.

Chỉnh sửa 2: cúi xuống (n˚). Chương trình đã ném lỗi. Tôi đã sửa nó lên. không thực sự 153 :(

Cảm ơn Leaky Nun vì đã tiết kiệm 5 byte và cho jmilloy để lưu 13 8 byte.

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

Chương trình chạy qua tất cả các chuỗi con có thể có trong đầu vào (có thể là có thể, vì nó cũng tính toán các chuỗi con không thể, ví dụ 8 đến 7), kiểm tra xem chuỗi con có "may mắn" hay không, sau đó đặt số mũ của 2 theo độ dài chuỗi con phải lớn hơn giá trị hiện tại. Có thể có thể được cải thiện bằng cách chỉ sử dụng một vòng lặp while. Có thể có thể sử dụng một số cải tiến; Tôi vẫn đang hiểu rõ điều này.


while p+1trở thànhwhile-~p
Leaky Nun

từ khi nào b=s[p:q], len(b)phải q-pđúng không?
Rò rỉ Nun

Tôi đã đánh cắp bạn phương thức nhập và in nhưng phần còn lại rất khác, cảm ơn! Tôi nghĩ rằng nếu bạn chỉ làm print(2**m-2*sum(i in"omen" for i in s))cho ba dòng cuối cùng của bạn, bạn sẽ làm tốt hơn, như 148?
jmilloy

Ồ, và bạn chỉ có thể di chuyển s [p: q] vào mệnh đề if while-~q:n=q-p;m=n if(s[p:q]in"lucky")*n>m else m;q-=1cho 143?
jmilloy

sum(map(s.count,"omen"))lưu một byte, làm cho nó 135
Black Owl Kai

1

Chương trình PHP, 139 135 108 byte

bước nhảy lượng tử thất bại cho nhiều chuỗi con trong đó lần xuất hiện đầu tiên ngắn hơn. :

thực sự tôi có thể lưu thêm 7 byte trong PHP <5.4 với register_globals trên

<?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);

sử dụng: php -d error_reporting=0 <filename> <string>

+5 cho một chức năng:

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

kiểm tra (về chức năng)

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

Scala, 155 byte

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.