ตัวเลขที่ไม่ถูกต้อง


16

undulantจำนวนเป็นจำนวนที่สลับตัวเลขระหว่างขึ้นและลงเช่นจำนวนต่อไปนี้: 461902 หรือ 708143 หรือแม้กระทั่ง 1010101 แต่ไม่ 123 เพราะ 2 <3

เขียนโปรแกรมหรือฟังก์ชั่นที่ส่งกลับค่าความจริงหากจำนวนนั้นไม่ถูกต้องและเป็นค่าเท็จ รหัสที่สั้นที่สุดชนะ

หมายเหตุ : ตัวเลขหลักเดียวเป็นอินพุตที่ถูกต้อง แต่ไม่ถือว่าเป็นudulantดังนั้นisUndulantจะส่งคืน false สำหรับ n <10


ใส่ตัวเลขเป็นสตริงจำนวนเต็มลอย ... ?
หยุดหมุนทวนเข็มนาฬิกาเมื่อ

1
ที่นี่มีวัตถุประสงค์อะไร? Code-golf (ฟังก์ชั่นที่สั้นที่สุด)?
Alexandru

1
@Bernardo: ฉันจะคิดว่าพฤติกรรมที่แท้จริงหรือไม่ได้กำหนดเพราะมันจะเป็นกรณีฐานที่ดีกว่าสำหรับการสอบถามซ้ำ
Joey Adams

4
ความหมายของจำนวน undulant ไม่ได้อยู่ในข้อตกลงกับความคมชัดมาตรฐาน: mathworld.wolfram.com/UndulatingNumber.html มันตั้งใจหรือไม่
mellamokb

9
โซลูชันของฉันอาจเล็กลง 16% ถ้ากรณีพื้นฐานเป็นจริง (ตามที่เข้าใจ IMHO)
รันดร์

คำตอบ:


6

J, 45

*./(n>9),(}:(=-)}.)(}:*@-}.)n#:~10$~>.10^.n=.

ตัวอย่างการใช้งาน:

   *./(n>9),(}:(=-)}.)(}:*@-}.)n#:~10$~>.10^.n=. 461902
1
   *./(n>9),(}:(=-)}.)(}:*@-}.)n#:~10$~>.10^.n=. 708143
1
   *./(n>9),(}:(=-)}.)(}:*@-}.)n#:~10$~>.10^.n=. 1010101
1
   *./(n>9),(}:(=-)}.)(}:*@-}.)n#:~10$~>.10^.n=. 123
0
   *./(n>9),(}:(=-)}.)(}:*@-}.)n#:~10$~>.10^.n=. 5
0

ฉันค่อนข้างมั่นใจว่ามีวิธีที่ดีกว่าในการบิดแทรก/เพื่อทำงานมากกว่าในระหว่างการเดินทาง แต่ฉันได้ J-less มาหลายเดือนฉันต้องกลับไป


มันจะยากที่จะเอาชนะ J ในปัญหานี้ ทางออกที่ดี!
Leonardo

@leonardo ขอบคุณ!
JB

6

Ruby, 72 70 ตัวอักษร

Q=10;k=->n,v{(n%Q-n/Q%Q)*v<0?k[n/Q,-v]:n<Q};u=->n{n>9&&k[n,-1]|k[n,1]}

การใช้งานและ testcases:

p u[10101]   # <= true
p u[708143]  # <= true
p u[2421]    # <= false
p u[1231]    # <= false
p u[873]     # <= false

ตัวเลขหลักเดียวให้ผลเป็นเท็จ :

p u[5]       # <= false

ตัวเลขที่เหมือนกันติดต่อกันจะคืนค่าเท็จเช่นกัน:

p u[66]      # <= false
p u[1221]    # <= false

6

J, 30 ไบต์

*/0<(#,]*{.*1 _1$~#)2-/\a.i.":

แนวทางที่แตกต่างจากคำตอบ J อื่น ๆ

   * / 0 <(#,] * {. * 1 _1 $ ~ #) 2 - / \ ai ": 461902
1
   * / 0 <(#,] * {. * 1 _1 $ ~ #) 2 - / \ ai ": 708143
1
   * / 0 <(#,] * {. * 1 _1 $ ~ #) 2 - / \ ai ": 1010101
1
   * / 0 <(#,] * {. * 1 _1 $ ~ #) 2 - / \ ai ": 123
0
   * / 0 <(#,] * {. * 1 _1 $ ~ #) (} .-} :) ai ": 5
0

จะสั้นกว่า 3 ตัวอักษรหากถือว่า 5 ไม่เหมาะ


อย่างน้อยฉันก็สามารถปลอบใจตัวเองด้วยความคิดที่ว่าฉันมีความเป็นผู้นำเป็นเวลาหนึ่งชั่วโมง :-)
Gareth

5

(pdf) eTeX, 129 ตัวอักษร

\def\a#1#2{\if#2?\ifx\r\s\def\s{1}\else
True\end\fi\fi\edef\t{\pdfstrcmp{#2}{#1}}\ifx\s\t
False\end\fi\let\s\t\a#2}\expandafter\a

การคอมไพล์ด้วยpdfetex filename.tex 1324?ให้เอาต์พุตแบบ pdf TeX เป็นภาษาหลักของการเรียงพิมพ์และการส่งออกไปยัง stdout จะใช้เวลามากกว่า 20 ตัวอักษร ข้อกำหนดที่แปลกสำหรับตัวเลขหนึ่งตัว (เท็จมากกว่าจริง) ทำให้ฉันมี 26 ตัวอักษร


5

Haskell, 88 77 73 65 ตัวอักษร

z=tail>>=zipWith compare
q[]=0>1
q s=all(/=EQ)$s++z s
u=q.z.show

นี้ต้องใช้ภาษาที่ใช้กันทั่วไป pragma (หรือธง):-X NoMonomorphismRestrictionหากคุณไม่ยอมรับเราต้องเพิ่ม 4 ตัวอักษรและกำหนดzดังนี้:

z s=zipWith compare s$tail s

ฉันโมโหมากที่คุณเอาชนะ 104 char ของฉัน u n=length s>1&&(a[GT,LT]||a[LT,GT])where s=show n;z=q compare s$tail s;w=q(==)z;q=zipWith;a=and.w.cycleมันค่อนข้างสง่างาม zipWithครั้งเดียวกับที่compareคุณทำแล้วzipWithอีกครั้งด้วย(==)และcycle[GT,LT]หรือcycle[LT,GT]เป็นที่สองหาเรื่อง
eternalmatt

คุณสามารถอินไลน์ w tail>>=zipWith compareซึ่งจะทำให้สั้นลงไม่กี่ไบต์
ภูมิใจ haskeller

นอกจากนี้ฉันเล่นกอล์ฟรุ่นสั้นลงของq:q[]=0<1;q(a:b:s)|a/=b,a/=EQ=q$b:s;q _=0>1
ภูมิใจ Haskeller

จริงๆแล้วนี่เป็นรุ่นที่สั้นกว่า: q s=and$all(/=EQ)s:zipWith(/=)s(tail s)
ภูมิใจ haskeller

@proudhaskeller - ทั้งสองเวอร์ชันไม่ผ่านการทดสอบทั้งหมด พวกเขาทั้งสองล้มเหลวในวันที่ 3 (ควรเป็นเท็จ) และครั้งแรกล้มเหลวอื่น ๆ อีกมากมายเช่น 32 และ 101010101
MtnViewMark

4

Sage, 83 76 ไบต์

f=lambda x:uniq(cmp(*`x`[i-2:i][::(-1)^i])for i in[2..len(`x`)])in[[1],[-1]]

มีแนวคิดที่จะใช้ cmp (* [.. ]) จาก JBernardo ใน Sage, เป็นนามแฝงสำหรับuniq(...)list(set(...))

แก้ไข: เพิ่งสังเกตเห็นว่าสำหรับ x <10 ซึ่งไม่ได้อยู่ในuniq(cmp(...)) == [] [[1],[-1]]ถ้า x เป็นอินพุตเป็นสตริงแทนที่จะเป็นจำนวนเต็มฉันสามารถลบอักขระได้อีก 4 ตัว!


ฉันมีความคิดที่จะใช้sum(uniq(...))^2ตั้งแต่sum([1,-1]) = 0และผลรวมของซิงเกิลตัน [1] และ [-1] กำลังสองถึง 1 แต่น่าเสียดายที่มันล้มเหลวด้วยตัวเลขสามหลักซ้ำ 1011101.
บูธโดย

ดี ฉันควรเรียนรู้ปราชญ์ BTW ฉันเพิ่งรู้ว่า backticks จะผนวกLถ้าจำนวนมากกว่า 2 ** 32 ใน Python และมีผลต่อผลลัพธ์ สิ่งนี้เกิดขึ้นกับ Sage หรือไม่?
JBernardo

ใช่ปราชญ์ทำให้บางสิ่งที่ดีสำหรับการเล่นกอล์ฟ ... เช่นเวลาเริ่มต้นที่ไร้สาระของมันจะถูกนำเข้าต้นไม้ใหญ่ของโมดูล คลาส Sage Integer ไม่ต้องกังวลกับLเพราะ Sage ถูกเตรียมการล่วงหน้า 1234 -> จำนวนเต็ม ('1234') คุณสามารถกระโดดไปสู่การใช้ Sage ได้ที่นี่: sagenb.org
boothby

4

Python: 101 100 ตัวอักษร

ก่อนการลดขนาด:

undulate = (lambda n: n > 9
            and all(cmp(*digits) == (i % 2) * 2 - 1
                    for i, digits
                    in enumerate(zip(min(`n`,`n`[1:]), 
                                     max(`n`,`n`[1:])))))

หลังจาก minification:

a=lambda b:b>9and all(cmp(*c)==d%2*2-1 for d,c in enumerate(zip(min(`b`,`b`[1:]),max(`b`,`b`[1:]))))

3

Python, 134 129 ตัวอักษร

def f(x):d=[cmp(*i)for i in zip(`x`,`x`[1:])]if x>9 else[0];n=d[0]>0;return all(i<0 for i in d[n::2])&all(i>0 for i in d[n<1::2])

Ungolfed:

def f(x):
    if x>9:
        d = [cmp(*i)for i in zip(`x`,`x`[1:])] #difference of x[i] and x[i+1]
    else:
        d = [0]       #trick to return False if x<10 using less chars
    n = d[0]>0        #First digit is -1 or 1?
    neg = d[n::2]     #negative numbers if x is Undulant
    pos = d[not n::2] #positive numbers if x is Undulant

    #check if all negs are -1 and all pos are 1 and return value
    return all(i<0 for i in neg) and all(i>0 for i in pos)

3

JavaScript, 88 ตัวอักษร

function _(i){i+='';c=i[0];f=i[a=x=1];for(g=f<c;d=i[x++];c=d)g^=a&=g?d<c:d>c;return!f^a}

ในสาระสำคัญเปลี่ยนหมายเลขเป็นสตริงและเปรียบเทียบอักขระที่อยู่ติดกันพลิกความคาดหวังสำหรับแต่ละ


2
ใน JavaScript ฟังก์ชันไม่จำเป็นต้องมีชื่อและคำถามจะถามอย่างชัดเจนถึงฟังก์ชั่นดังนั้นคุณสามารถบันทึกอักขระสองตัวได้
Ry-


3

CoffeeScript, 98 67 53 ไบต์

(n)->0!in((n[i]>=c^(n[0]<n[1])+i)%2for c,i in n[1..])

แบบทดสอบ:

[
    '01010101' # true
    '12345'    # false
    '1010101'  # true
    '887685'   # false
    '9120734'  # true
    '090909'   # true
]

ไม่มีการบีบอัด:

undulant = (n) ->
    direction = n[0] < n[1]
    return n.split('').every (cur, i) ->
        prev = arr[i-1] or 10 * direction
        +(prev >= cur) is (direction+i)%2

3

J, 44 39 36 31 ไบต์

*/2(0<#@],0>*/\)*2-/\".;' ',.":

การใช้งานเหมือนก่อน

ฉันไม่ได้สังเกตว่าการแก้ไขครั้งล่าสุดของฉันทำให้ความไม่เท่าเทียมกับการตรวจสอบ 0 ไม่จำเป็นอย่างสมบูรณ์ :-)

คำตอบก่อนหน้า (+ คำอธิบาย):

(0=+/2=/\u)*(1<#u)**/2~:/\2<:/\u=.".;' ',.":

การใช้งาน:

    (0=+/2=/\u)*(1<#u)**/2~:/\2<:/\u=.".;' ',.":461902
1

คำตอบมีสี่ส่วน:

  1. u=.".;' ',.": สิ่งนี้จะอ่านตัวเลขเป็นสตริง":แยกออกเป็นรายการของอักขระนำหน้าด้วยการเว้นวรรคเชื่อมต่อ' ',.กลับเข้าด้วยกัน;แปลงกลับเป็นตัวเลข".แล้วเก็บผลลัพธ์u=.นี้โดยทั่วไปแล้วจะเปลี่ยน 461902 เป็น 4 6 1 9 0 2 ซึ่งฉันหาง่ายขึ้น เพื่อดำเนินการในเจ

  2. */2~:/\2<:/\ สิ่งนี้ทำงานกับค่าที่เก็บใน u มันต้องใช้อักขระแต่ละคู่และตรวจสอบว่าตัวที่เหลือน้อยกว่าหรือเท่ากับที่ถูกต้อง2<:/\ดังนั้น 4 6 1 9 0 2 กลายเป็น 1 0 1 0 1 1. จากนั้นจะรับผลลัพธ์ของสิ่งนี้และตรวจสอบความไม่เท่าเทียมกันแต่ละคู่2~:/\ดังนั้น 1 0 1 0 1 กลายเป็น 1 1 1 1. ในที่สุดมันก็คูณพวกมันทั้งหมดเข้าด้วยกันเพื่อให้ได้ 0 หรือ 1 */ณ จุดนี้เราสามารถคืนคำตอบถ้ามันไม่ใช่ 2 สิ่ง: หลักเดียวส่งกลับ 1 เมื่อ คำถามต้องมี 0; และจำนวนที่เท่ากันจะได้รับการปฏิบัติเหมือนกับ 'น้อยกว่า' ดังนั้น 461900 จึงส่งกลับ 1 แทน 0 Bummer เราไป ...

  3. (1<#u) การตรวจสอบนี้จะตรวจสอบว่าจำนวนรายการที่จัดเก็บใน u #uมากกว่า 1 และส่งกลับเท็จถ้ามันเป็นเพียงตัวเลขหลักเดียว

  4. (0=+/2=/\u)2=/\uนี้จะใช้เวลาคู่ของตัวเลขที่เก็บไว้ในยูและการตรวจสอบเพื่อความเท่าเทียมกันในแต่ละ จากนั้นจะรวมคำตอบและตรวจสอบว่ามี 0 หรือไม่

ผลลัพธ์ของส่วนที่ 2, 3 และ 4 จะถูกคูณเข้าด้วยกันเพื่อ (หวังว่า) จะสร้าง 1 เมื่อตัวเลขตรงตามข้อกำหนดที่ระบุในคำถาม


เยี่ยมมากการเป็นผู้นำ แต่ฉันยืมเคล็ดลับจากคุณ!
ephemient

(ที่ถูกกล่าวว่าฉันคิดว่าคุณสามารถใช้ของฉันที่a.i.":จะโกนตัวละครอีกสองสามตัวออกไป)
ephemient

น่าเสียดายที่ฉันอาจต้องตรวจสอบความไม่เท่าเทียมกันอีกครั้ง - คำตอบของฉันล้มเหลวในขณะนี้สำหรับ 11, 22, 33, 44 และอื่น ๆ
Gareth

3

Haskell, 82 ไบต์

c=cycle[(<),(>)]
l!n=n>9&&and(zipWith3($)l(show n)$tail$show n)
u n=c!n||((>):c)!n

ลองออนไลน์!


ฉันนับได้เพียง 83 ตัวในโซลูชันนี้ (คุณอยู่บน Windows หรือไม่เขียนไฟล์ด้วยปลายสายยูนิกซ์ซึ่งเป็นกฎหมาย Haskell)
MtnViewMark

ขอบคุณฉันใช้ 'wc' เพื่อนับตัวละครของฉันใน Cygwin ฉันนับ 82 ตัวอักษร ฉันใช้รหัสต่อไปนี้เนื่องจาก wc ดูเหมือนว่าจะแสดงผลอักขระพิเศษ (กลุ่มไม่แสดงบรรทัดใหม่ที่ตามมา แต่แผ่นจดบันทึกจะทำ ... ) readFile "Undulant.hs" >>= print . length . dropWhile (== '\n') . reverse . filter (/= '\r')
Thomas Eding

c=cycle[(<),(>)]c=(<):(>):cสามารถลงไป
Laikoni

1
zipWith3($)l(show n)$tail$show nสามารถzipWith3($)l=<<tail$show nและสามารถ((>):c) tail cรวมกัน 70 ไบต์: ลองออนไลน์!
Laikoni

3

Python 119 108 ไบต์

def u(x):l=[cmp(i,j)for i,j in zip(`x`,`x`[1:])];print x>9and all([i*j<0 for i,j in zip(l,l[1:])])and l!=[0]

2
การใช้งานที่ดีของ xor คุณสามารถตัดตัวอักษรออกได้เล็กน้อย... for a,b in zip(t,t[1:])แทนที่จะใช้ช่วง นอกจากนี้คุณไม่จำเป็นต้องใช้เครื่องหมายวงเล็บในall([...])- Python สร้างเครื่องมือสร้างขึ้นเมื่อพบ(... for ...)แม้ว่าจะใช้วงเล็บในการเรียกใช้ฟังก์ชัน
บูธ

ขอบคุณมากสำหรับคำแนะนำของคุณ! พวกเขามีค่ามาก! -20 ตัวอักษร
คิริลล์

ทางออกที่ดีมาก ตัวอักษรไม่กี่และลบx>9 and all(i^j for i,j in zip(l,l[1:])) if l else False
Ante

1
It is not working in all cases. Two cases are problematic: only 2 digits (e.g. 11), and last 2 digits are same and larger than one before (e.g. 12155). First problem is since there is no testing if x<100. Second is because 'one way comparison'. It can be fix with cmp(i,j) and instead i^j set i*j<0, and testing and l[0]!=0. Few more characters :-/
Ante

1
Hmmm... print saves one character over return, but is it legitimate? The spec does ask for a function that "returns".

2

Python, 155 chars

g=lambda a,b:all(x>y for x,y in zip(a,b))
u=lambda D:g(D[::2],D[1::2])&g(D[2::2],D[1::2])
def U(n):D=map(int,str(n));return(n>9)&(u(D)|u([-d for d in D]))

2

C++, 94 chars

bool u(int N){int K,P,Q,U=1,D=1;while(N>9)P=N%10,Q=(N/=10)%10,K=D,D=U&Q<P,U=K&Q>P;return U^D;}

same method as my Erlang awnser with a for loop rather than recursion.


2

Python 105 101 100 chars

c=lambda r,t:len(r)<2 or(cmp(*r[:2])==t and c(r[1:],-t))
u=lambda x:x>9and c(`x`,cmp(*`x`[:2])or 1)

Recursive solution. c(r,t) checks if first char of r is less (t==-1) or greater (t==1) of second char, and call opposite check on shortened string.


Nice. You can save a character in the first line by removing 0, and you can save three characters on the second line by writing u=lambda x:x>9 and c(`x`,cmp(*`x`[:2])or 1)

Tnx. I didn't like any() from the beginning :-)
Ante

You can save one more by writing x>9and.

2

Perl/re, 139 bytes

Doing everything in regex is kind of a bad idea.

/^(?:(.)(?{local$a=$1}))?(?:(?>((.)(?(?{$a lt$3})(?{local$a=$3})|(?!)))((.)(?(?{$a gt$5})(?{local$a=$5})|(?!))))*(?2)?)(?(?{pos>1})|(?!))$/

I'm using Perl 5.12 but I think this will work on Perl 5.10. Pretty sure 5.8 is out though.

for (qw(461902 708143 1010101 123 5)) {
    print "$_ is " . (/crazy regex goes here/ ? '' : 'not ') . "undulant\n";
}

461902 is undulant
708143 is undulant
1010101 is undulant
123 is not undulant
5 is not undulant


2

JavaScript, 66 65 62 60 bytes

Takes input as a string, returns true for undulant numbers, an empty string (falsey) for single digit numbers and false otherwise.

([s,...a])=>a+a&&a.every(x=>eval(s+"<>"[++y%2]+x,s=x),y=s<a)

Try it

Run the Snippet below to test 0-9 and 25 random numbers <10,000,000.

f=
([s,...a])=>a+a&&a.every(x=>eval(s+"<>"[++y%2]+x,s=x),y=s<a)
tests=new Set([...Array(10).keys()])
while(tests.add(Math.random()*1e7|0).size<35);
o.innerText=[...tests].map(x=>(x=x+``).padStart(7)+` = `+JSON.stringify(f(x))).join`\n`
<pre id=o></pre>


Explanation

A few fun little tricks in this one so I think it warrants a rare explanation to a JS solution from me.

()=>

We start, simply, with an anonymous function which takes the integer string as an argument when called.

[s,...a]

That argument is immediately destructured into 2 parameters: s being the first character in the string and a being an array containing the remaining characters (e.g. "461902" becomes s="4" and a=["6","1","9","0","2"]).

a+a&&

First, we concatenate a with itself, which casts both occurrences to strings. If the input is a single digit number then a will be empty and, therefore, become and empty string; an empty string plus an empty string is still an empty string and, because that's falsey in JS, we stop processing at the logical AND and output our empty string. In all other cases a+a will be truthy and so we continue on to the next part of the function.

a.every(x=>)

We'll be checking if every element x in a returns true when passed through a function.

y=s<a

This determines what our first comparison will be (< or >) and then we'll alternate from there. We check if the string s is less than the array a, which gets cast to a string in the process so, if s is less than the first character in a, y will be true or false if it's not.

s+"<>"[++y%2]+x

We build a string with the current value of s at the beginning and x at the end. In between, we index into the string "<>" by incrementing y, casting its initial boolean value to an integer, and modulo by 2, giving us 0 or 1.

eval()

Eval that string.

s=x

Finally, we pass a second argument to eval, which it ignores, and use it to set the value of s to the current value of x for the next iteration.



1

JavaScript, 112

function(n,d,l,c,f){while(l=n%10,n=n/10|0)d=n%10,c?c>0?d>=l?(f=0):(c=-c):d<=l?(f=0):(c=-c):(c=d-l,f=1);return f}

You only need to pass it one argument. I could probably golf this further with a for loop.


(d>=l -> d>0) and (d<=l -> d<2) perhaps? I'm not looking closely, as perhaps d might contain fractional parts that might skew it.
Thomas Eding

@trinithis: That's a lowercase L, not a 1. Thanks though!
Ry-

Where's DejaVu Sans Mono or Bitstream Vera Sans Mono when you need it? Perhaps I need to customize stackoverflow with some custom css or a user script...
Thomas Eding

@trinithis: I agree, the font choice isn't that great. Bolding doesn't stand out enough...
Ry-

1

Erlang, 137 123 118 chars

u(N)->Q=N div 10,u(Q,N rem 10,Q>0,Q>0). u(0,_,D,U)->D or U;u(N,P,D,U)->Q=N rem 10,u(N div 10,Q,U and(Q<P),D and(Q>P)).

Won't this return True so long as there has been at least one up and one down transition anywhere? Won't it return True for, say 1234321?
MtnViewMark

@ MtnViewMark, yeah it did thanks, I misunderstood the question fixed now hopefully.
Scott Logan

1

CJam, 30 bytes

CJam is newer than this challenge, so this does not compete for the green checkmark, but it's not a winner anyway (although I'm sure this can actually be golfed quite a bit).

l"_1=\+{_@-\}*;]"_8'*t+~{W>},!

Test it here.

How it works

Firstly, I'm doing some string manipulation (followed by eval) to save 5 bytes on duplicate code:

"..."_8'*t+~
"..."        "Push this string.":
     _       "Duplicate.";
      8'*t   "Replace the 8th character (the -) with *.";
          +~ "Concatenate the strings and evaluate.";

So in effect my code is

l_1=\+{_@-\}*;]_1=\+{_@*\}*;]{W>},!

First, here is how I deal with the weird special case of a single digit. I copy the digit at index 1 and prepend it to the number. We need to distinguish 3 cases:

  • The first two digits are different, like 12..., then we get 212..., so the start is undulant, and won't affect whether the entire number is undulant.
  • The first two digits are the same, like 11..., then we get 111.... Now the start is not undulant, but the number wasn't undulant anyway, so this won't affect the result either.
  • If the number only has one digit, the digit at index 1 will be the first digit (because CJam's array indexing loops around the end), so this results in two identical digits, and the number is not undulant.

Now looking at the code in detail:

l_1=\+{_@-\}*;]_1=\+{_@*\}*;]{W>},!
l                                   "Read input.";
 _1=\+                              "Prepend second digit.";
      {_@-\}*                       "This fold gets the differences of consecutive elments.";
             ;]                     "Drop the final element and collect in an aray.";
               _1=\+                "Prepend second element.";
                    {_@*\}*         "This fold gets the products of consecutive elments.";
                           ;]       "Drop the final element and collect in an aray.";
                             {W>},  "Filter out non-negative numbers.";
                                  ! "Logical not.";

I'm sure there is a shorter way to actually check digits (of length greater 1) for whether they are undulant (in particular, without using two folds), but I couldn't find it yet.


1

Prolog 87 bytes

u(X) :- number_codes(X,C),f(C).
f([_,_]).
f([A,B,C|L]) :- (A<B,B>C;A>B,B<C),f([B,C|L]).

To run it, just save it as golf.pl, open a prolog interpreter (e.g. gprolog) in the same directory then do:

consult(golf).
u(101010).

It will give true if the number is undulant, otherwise just no.


1

Mathematica, 46 bytes

#!=Sort@#&&#!=Reverse@Sort@#&[IntegerDigits@n]

Examples (spaces are not required):

# != Sort@# && # != Reverse@Sort@# &[IntegerDigits@5]
# != Sort@# && # != Reverse@Sort@# &[IntegerDigits@123]
# != Sort@# && # != Reverse@Sort@# &[IntegerDigits@132]
# != Sort@# && # != Reverse@Sort@# &[IntegerDigits@321]

(*  out *)
False  False  True  False

1

Scala, 141 133 129 97 bytes

def u(n:Int):Boolean=n>9&&{
val a=n%10
val b=(n/10)%10
a!=b&&n<99||(a-b*b-(n/100)%10)<0&&u(n/10)}

With a = n % 10, b = (n/10) % 10, c = (n/100) % 10

if a > b and b < c or 
   a < b and b > c

Then a-b * b-c is either x*-y or -x*y with x and y as positive numbers, and the product is in both cases negative, but for -x*-y or x*y (a < b < c or a > b > c) the product is always positive.

The rest of the code is handling special cases: one digit, two digits, two identical digits.



1

Q, 71 bytes

{$[x>9;any all a=#[;(1 -1;-1 1)](#)a:1_signum(-':){"I"$x}each -3!x;0b]}

Sample usage:

q){$[x>9;any all a=#[;(1 -1;-1 1)](#)a:1_signum(-':){"I"$x}each -3!x;0b]} 5
0b
q){$[x>9;any all a=#[;(1 -1;-1 1)](#)a:1_signum(-':){"I"$x}each -3!x;0b]} 10101
1b
q){$[x>9;any all a=#[;(1 -1;-1 1)](#)a:1_signum(-':){"I"$x}each -3!x;0b]} 01010
1b
q){$[x>9;any all a=#[;(1 -1;-1 1)](#)a:1_signum(-':){"I"$x}each -3!x;0b]} 134679
0b
q){$[x>9;any all a=#[;(1 -1;-1 1)](#)a:1_signum(-':){"I"$x}each -3!x;0b]} 123456
0b
q){$[x>9;any all a=#[;(1 -1;-1 1)](#)a:1_signum(-':){"I"$x}each -3!x;0b]} 132436
1b

You can logic away the if {(x>9)&any all a=#[;(1 -1;-1 1)](#)a:1_signum(-':)("I"$')($)x} gives 62
skeevey

Never seen ($) syntax for string before and the logic is a nice touch.
tmartin

1

Julia 0.6, 62 bytes

f(x,a=sign.(diff(digits(x))))=x>9&&-a*a[1]==(-1).^(1:endof(a))

Takes in a number, returns true for Undulant, and false for not. Eg f(163) returns true.

f(x,a=sign.(diff(digits(x))))=x>9&&-a*a[1]==(-1).^(1:endof(a))
f(x,                        )                                   # function definition
    a=sign.(diff(digits(x)))                                    # default 2nd argument is array of differences of signs of digits
                              x>9&&                             # short circuiting and to catch cases under 10
                                   -a*a[1]                      # make the first element of a always -1
                                          ==(-1).^(1:endof(a))  # check that a is an array of alternating -1 and 1 of correct length

Try it online!

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