พิจารณา“ โชค” ของสตริง


35

รับสตริงส่งคืน "โชค" ของสตริงนั้น

โชคของสตริงในขณะที่ฉันทำขึ้นเพื่อจุดประสงค์ของการท้าทายนี้โดยสมบูรณ์เป็นจำนวนเต็มพิจารณาดังนี้:

  • โชคพื้นฐานสำหรับสตริงคือ 1
  • สำหรับแต่ละตัวอักษรที่ต่อเนื่องกันจะแบ่งปันด้วยคำว่า "lucky" (ไม่คำนึงถึงขนาดตัวพิมพ์) คูณโชคด้วย 2 ตัวอย่างเช่นถ้าสตริงของคุณคือ " lu mberjack" หรือ "sma ck " คุณจะคูณด้วย 4 (เพิ่มเติมโดยเฉพาะ แบ่งปันอักขระต่อเนื่อง 2 ^ ตัว)
    • ตัวอักษรที่ใช้ร่วมกันจะต้องอยู่ในลำดับเดียวกันนั้นปรากฏใน "lucky" แต่สามารถเริ่มที่ใดก็ได้ในคำสำหรับค่าเดียวกัน ("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 คุณจะถูกส่งผ่านStringและส่งคืนNumber)

แก้ไข: คุณสามารถสมมติว่าอินพุตใด ๆ เป็นตัวพิมพ์เล็ก


8
ความท้าทายแรกที่ดี!
Alex A.

2
โปรแกรมควรยอมรับอินพุตตัวพิมพ์ใหญ่หรือไม่?
busukxuan

2
@busukxuan เป็นคำถามที่ดี - ไม่ไม่จำเป็นต้องยอมรับอินพุตตัวพิมพ์ใหญ่
charredgrass

@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 ไบต์ขอบคุณAdnan


การบีบอัดสำหรับ 1 คำสามารถทำได้ด้วย'ดังนั้นสำหรับ 26: Œv'¸éyåiyˆ}}¯é¤go¹'ƒÖ¦Ãg·-:)
Adnan

@Adnan: แปลก ฉันแน่ใจว่าฉันได้ลองสิ่งนั้นแล้ว ชัดเจนว่าไม่. ขอบคุณ!
Emigna

ทำไมนี่ไม่ใช่คำตอบยอดนิยม
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ผลการแข่งขัน
Neil

1
สี่สำหรับสตริงและคู่ของ()ในกรณีนี้ match(/[omen]/)กินทั้งหกที่คุณจะประหยัดด้วย สงสาร
ติตัส

1
@Titus ไม่แน่ใจว่านั่นคือสิ่งที่คุณหมายถึง แต่โดยการเพิ่มLไปยังจุดสิ้นสุดของ substr (ซึ่งจะไม่ปรากฏในสตริงเดิม) ฉันไม่ต้องกังวลเกี่ยวกับการแข่งขันภายนอกและฉันสามารถใช้อาร์เรย์เดียวกัน[5,4,3,2,1,0]ทั้งสองครั้งจริง ๆ ประหยัดมหันต์ 13 ไบต์!
Neil

1
-2*s.split(/[omen]/).length+2สั้นกว่า
Oriol

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
ดูเหมือนจะไม่ทำงานกับสตริงโดยไม่มีตัวอักษรในรูปแบบ "โชคดี" ในนั้น ตัวอย่างเช่น "memes"
Emigna

1
@Emigna Ah กรณีเป็นศูนย์อีกครั้ง .... ขอบคุณแก้ไขมัน!
busukxuan

6

Ruby, 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มากกว่าฟังก์ชั่นหรือไม่?
Downgoat

1
@ ลงไปถ้าฉันgetsฉันยังต้องมีการputsส่งออกดังนั้นไม่ได้ในกรณีนี้
หมึกมูลค่า

4

Ruby: 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]/regex เพื่อตีมันลง - มันจะจับคู่กับตัวละครใด ๆ และใช้งานได้ดีกว่าการผูกมัด|สำหรับอักขระเดี่ยว
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)(สมมติว่านี้จะจาวาสคริปต์)
charredgrass

ขอบคุณสำหรับเคล็ดลับ! รับลงไปที่ 237 แม้ว่ามันจะดูเหมือนว่าฝูงชนของ Ruby ทำให้ฉันชนะ
Christopher Burgdorff

สิ่งเล็ก ๆ น้อย ๆ อีกอย่างหนึ่ง: คุณสามารถจดย่อfunction luck(r)เพื่อr=>ทำหน้าที่เป็นแบบไม่ระบุชื่อนั่นคือทั้งหมดที่จำเป็นสำหรับการท้าทายนี้ นอกจากนี้ฉันได้แก้ไขความท้าทายเพื่อให้คุณไม่ต้องกังวลเกี่ยวกับกรณีเพื่อให้คุณสามารถลบr=r.toLowerCase();
charredgrass

แทนคุณsubstringสามารถใช้sliceฉันเชื่อ (ทดสอบสิ่งนี้แม้ว่าฉันไม่แน่ใจ)
Downgoat

3

Ruby, 57 ไบต์

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

getsตั้งค่า$.เป็น 1 เป็นผลข้างเคียงจากนั้นเราจะเพิ่มมันจนกว่านิพจน์ปกติที่ตรงกับ$.ตัวอักษรนำโชคต่อเนื่องจะไม่ตรงกันอีกต่อไป


3

Haskell, 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 ไบต์

แข็งแรงเล่นกอล์ฟ:

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 เช่นกัน แต่สามารถจัดการกับปัญหาบางอย่างได้ด้วยการเปลี่ยนอัลกอริธึมเล็กน้อยและใช้ชื่อแทนฟังก์ชันกับฟังก์ชันที่นำกลับมาใช้ใหม่
Zylviij

1

Python 3, 168 157 152 139 144 136 136

แก้ไข: สิ่งที่ชัดเจนจริง ๆ ที่ฉันควรเห็นได้ง่ายขึ้นมีการเปลี่ยนแปลงและบางอย่างชัดเจนน้อยกว่าเล็กน้อย

แก้ไข 2: stoopid (˚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))

โปรแกรมทำงานผ่าน substrings ที่เป็นไปได้ทั้งหมดในอินพุต (อาจเป็นไปได้เนื่องจากมันคำนวณ substrings ที่เป็นไปไม่ได้เช่น 8 ถึง 7 เป็นต้น) ตรวจสอบว่า substring อยู่ใน "lucky" จากนั้นตั้งค่า exponent เป็น 2 ตามความยาวของ ซับสตริงควรมากกว่าค่าปัจจุบัน อาจปรับปรุงได้โดยใช้เพียงหนึ่งเดียวขณะวนซ้ำ อาจใช้การปรับปรุงบางอย่าง; ฉันยังคงได้รับสิ่งนี้


while p+1กลายเป็นwhile-~p
Leun Nun

ตั้งแต่b=s[p:q], len(b)ต้องq-pใช่มั้ย?
Leun Nun

ฉันขโมยวิธีการป้อนข้อมูลและการพิมพ์ของคุณ แต่ส่วนที่เหลือแตกต่างกันมากขอบคุณ! ฉันคิดว่าถ้าคุณทำ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-=1143 ได้ไหม
jmilloy

sum(map(s.count,"omen"))บันทึกหนึ่งไบต์ทำให้มันเป็น 135
Black Owl Kai

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.