22
\$\begingroup\$

A pleasing number (according to this definition) is a number that can be passed through the following process (let's use 41802000 as an example):

  • Separate the trailing identical numbers (41802000 => [41802, 000])
  • Sort the first half of the digits and take the maximum ([41802, 000] => [8, 000])
  • Take the length of the final element. Call the resultant elements A and B ([8, 000] => A=8, B=3)
  • Is NB = A for any integer N? (True in this example; 23 = 8)

If the input results in True from the following process, it is considered pleasing.

Your task is to take an integer x, and output whether x is a pleasing number. You can output any two distinct values for truthy and falsey, but please state what you're using in your answer. x is guaranteed to have at least two distinct digits (e.g. 111 is an invalid input). As with most challenges, you may take x as a string, or a list of digits.

This is a so shortest code in bytes wins.

Test cases

          Input          Output
       41802000               1
            100               1
      123456788               0
      451111111               0
234543454545444               0
             12               1
       41902000               0
          92599               1
\$\endgroup\$
  • \$\begingroup\$ can the number be passed as a string? (especially given the '234543454545444' test case) \$\endgroup\$ – Uriel Dec 17 '17 at 21:08
  • \$\begingroup\$ @Uriel You may take input as a string \$\endgroup\$ – caird coinheringaahing Dec 17 '17 at 21:10
  • 3
    \$\begingroup\$ As a suggestion for clarification: I would use the term "digit" rather than "number", as you are specifically referring to the decimal characters, abstracted from their number values. \$\endgroup\$ – Jonathan Frech Dec 17 '17 at 22:43
  • \$\begingroup\$ list of digits - would this be a list of the ASCII numeral characters, or a list of integers from 0-9 \$\endgroup\$ – Οurous Dec 17 '17 at 23:05
  • 1
    \$\begingroup\$ @Οurous Up to you \$\endgroup\$ – caird coinheringaahing Dec 17 '17 at 23:08

26 Answers 26

9
\$\begingroup\$

APL (Dyalog), 36 bytes

{(⊢≡⌊)(⌈/⍎¨⍵/⍨~o)*÷≢⍵/⍨o←⌽⌊\1,2=/⌽⍵}

Try it online!

How?

Almost a poem.

⌽⍵ - reverse the input once,

1,2=/ - get the differences list.

⌊\ - keep only the first group of ones,

- and flip it over to complete.


o← - assign to o,

~o - switch ones and zero(s),

⍵/⍨ - filter the input with it,

⍎¨ - turn the result into list of each digit,

  • ⌈/ - and get the maximum. (that's A)

⍵/⍨o - filter the input with o unalt(ered),

- and take the length, that would be B.

÷ - get one divided by this result,

* - and take A to that power thee.


⊢≡⌊ - integer?

\$\endgroup\$
8
\$\begingroup\$

05AB1E, 11 bytes

γRćgUZXzm.ï

Try it online!

Explanation

γRćgUZXzm.ï ~ Full program.

γ           ~ Split into runs of digits.
 R          ~ Reverse.
  ć         ~ Push a[1:], a[0] to the stack.
   g        ~ Length (of a[0]).
    U       ~ Assign this to the integer variable X.
     ZX     ~ Get the maximum, without popping, and push X.
       zm   ~ A1/B.
         .ï ~ Is it an integer?

Emigna saved 1 byte.

Relies on the fact that if A is a positive integer N raised to the power of B, then N=A1/B, hence it must be an integer.

\$\endgroup\$
  • \$\begingroup\$ UZX should work instead of s{θs \$\endgroup\$ – Emigna Dec 17 '17 at 21:07
  • \$\begingroup\$ The 9-byte program fails for 41902000 (should be falsy). \$\endgroup\$ – Zgarb Dec 17 '17 at 21:18
  • \$\begingroup\$ @Zgarb Yeah I was nearly sure it would fail, so I removed it... Also lol we got the exact same integer \$\endgroup\$ – Mr. Xcoder Dec 17 '17 at 21:18
  • \$\begingroup\$ Fails for 418802000 \$\endgroup\$ – Okx Apr 1 '18 at 12:59
8
\$\begingroup\$

Haskell, 85 75 72 71 bytes

Edit: -10 bytes by taking a list of digits instead of a string. Thanks to WhatToDo for pointing out that this is allowed. -3 bytes thanks to Ourous' solution in Clean. -1 byte thanks to user28667.

f s|(b,a)<-span(==last s)$reverse s=or[n^length b==maximum a|n<-[1..9]]

Try it online! Takes input as a list of digits. Example usage: f [4,1,8,0,2,0,0,0] yields True.

Explanation:

Given an input s=[4,1,8,0,2,0,0,0], we reverse the list and separate the leading elements with span(==last s): ([0,0,0],[2,0,8,1,4]). The pattern matching on (b,a) yields b=[0,0,0] and a=[2,0,8,1,4].

The list comprehension or[n^length b==maximum a|n<-[1..a]] checks whether any integer n in the range from 1 to 9 satisfies n^length b==maximum a, that is n^3=8.

\$\endgroup\$
  • \$\begingroup\$ You posted yours before I did mine, and ours are similar, so: Try it online! \$\endgroup\$ – WhatToDo Dec 17 '17 at 22:38
  • \$\begingroup\$ @WhatToDo Thanks, I didn't see that lists of digits where allowed as input. \$\endgroup\$ – Laikoni Dec 17 '17 at 22:51
  • \$\begingroup\$ Can’t you just take the maximum. No need to check them all. \$\endgroup\$ – Tim Dec 18 '17 at 11:17
  • \$\begingroup\$ @Tim I'm not sure I understand what you mean. Taking the maximum of the whole input list to get a would fail in cases like 477. \$\endgroup\$ – Laikoni Dec 18 '17 at 11:36
  • \$\begingroup\$ @Tim I do take the maximum to get b, but check every integer n from 0 to 9 (formerly from 0 to a). That's exactly the specification as far as I see. \$\endgroup\$ – Laikoni Dec 18 '17 at 11:52
5
\$\begingroup\$

Haskell, 104 89 bytes

@Laikoni found a shorter solution, but this is the best I could do. Thanks @Laikoni for letting me know that we can also accept lists of digits as input.

import Data.List
(g.length.last<*>maximum.concat.init).group
g b a=any(==a)$(^b)<$>[1..a]

Explanation:

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Why use any(==a) when you could use elem a? \$\endgroup\$ – Sriotchilism O'Zaic Dec 19 '17 at 15:40
  • \$\begingroup\$ @WheatWizard Thanks for the suggestions, regarding your second comment: Wouldn' this fail for e.g. 2888? \$\endgroup\$ – flawr Dec 19 '17 at 15:57
  • \$\begingroup\$ Yes it seems I misread the question. I didn't realize that the trailing numbers could be anything other than zero. \$\endgroup\$ – Sriotchilism O'Zaic Dec 19 '17 at 16:01
  • \$\begingroup\$ but head.maximum is still shorter than maximum.concat by 2 bytes, and maintains the functionality. \$\endgroup\$ – Sriotchilism O'Zaic Dec 19 '17 at 16:01
4
\$\begingroup\$

R, 80 bytes

function(x)any((0:(m=max((d=rle(rev(utf8ToInt(c(x,''))-48)))$v[-1])))^d$l[1]==m)

Try it online!

Uses utf8ToInt - 48 to split the number into digits. This throws a warning from the conversion to a string.

Using rle get the count of the trailing digits and the max value of the first digits. Return true if the any of the range 0 to max value to the power of trailing count equals max value.

I think there are further golfing opportunities, but that can wait until tomorrow.

\$\endgroup\$
  • 2
    \$\begingroup\$ I deleted my answer because I didn't see that my post was just combining your answer and @NofP's: function(x,R=rle(rev(utf8ToInt(x)-48)))!max(R$v[-1])^(1/R$l[‌​1])%%1 (66 bytes, taking x as a string) \$\endgroup\$ – plannapus Dec 18 '17 at 12:25
  • \$\begingroup\$ @plannapus Personally I would undelete it. It's a better count than both of ours and not really a copy of either \$\endgroup\$ – MickyT Dec 18 '17 at 17:22
  • \$\begingroup\$ @plannapus I agree with MickyT! \$\endgroup\$ – NofP Dec 18 '17 at 21:04
  • \$\begingroup\$ @NofP and MickyT: OK then, here it is \$\endgroup\$ – plannapus Dec 19 '17 at 8:37
4
\$\begingroup\$

Jelly, 11 bytes

ŒgµṪL9*€fṀL

Takes input as a list of digits.

Try it online!

How it works

ŒgµṪL9*€fṀL  Main link. Argument: D (digit array)

Œg           Group runs of digits, yielding a run array R.
  µ          Begin a new chain with argument D.
   Ṫ         Tail; remove and yield the last element of D.
    L        Take the length. Let's call it b.
     9*€     Compute [1**b, ..., 9**b].
         Ṁ   Take the maximum run in R, yileding [a, ..., a].
        f    Filter, yielding either [a] (if a = n**b for some n) or [].
          L  Take the length. 
\$\endgroup\$
  • \$\begingroup\$ Before looking at the answers, and without knowing Jelly at all, I guessed that the Jelly answer would be 12 bytes. ;) \$\endgroup\$ – DLosc Apr 3 '18 at 23:15
4
\$\begingroup\$

R, 66 bytes

This answer is more or less a medley of MickyT and NofP's answers, and on their request, here it is:

function(x,R=rle(rev(utf8ToInt(x)-48)))!max(R$v[-1])^(1/R$l[1])%%1

It takes x as a string.

> f=function(x,R=rle(rev(utf8ToInt(x)-48)))!max(R$v[-1])^(1/R$l[1])%%1
> f("41802000")
[1] TRUE
> f("100")
[1] TRUE
> f("123456788")
[1] FALSE
> f("451111111")
[1] FALSE
> f("234543454545444")
[1] FALSE
> f("12")
[1] TRUE
> f("41902000")
[1] FALSE
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES7), 66 bytes

Takes input as either a string or an array of characters. Returns a boolean.

f=([c,...s],m)=>s.some(n=>n-c)?f(s,c<m?m:c):!(m**(1/-~s.length)%1)

Test cases

f=([c,...s],m)=>s.some(n=>n-c)?f(s,c<m?m:c):!(m**(1/-~s.length)%1)

console.log(f(       '41802000')) // 1
console.log(f(            '100')) // 1
console.log(f(      '123456788')) // 0
console.log(f(      '451111111')) // 0
console.log(f('234543454545444')) // 0
console.log(f(             '12')) // 1

\$\endgroup\$
3
\$\begingroup\$

Clean, 130 128 118 93 bytes

import StdEnv
@l#(b,a)=span((==)(last l))(reverse l)
=or[n^length b==last(sort a)\\n<-[0..9]]

Defines the function @, taking a list of integer digits.

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Python 2, 95 78 bytes

  • Saved seventeen bytes thanks to Rod.
def f(s,i=~0):
	while s[i]==s[~0]:i-=1
	return int(max(s[:-~i]))**(1./~i)%1==0

Try it online!

\$\endgroup\$
  • \$\begingroup\$ You don't need o sort, you can just get the max, and since you already got i you can drop the len reaching 78 bytes \$\endgroup\$ – Rod Dec 18 '17 at 10:17
  • \$\begingroup\$ @Rod Thanks a lot. \$\endgroup\$ – Jonathan Frech Dec 18 '17 at 18:48
2
\$\begingroup\$

R, 93 bytes

function(x){n=nchar(x)
d=x%/%10^(n:1-1)%%10
i=max(which(d!=d[n]))
max(d[1:i])^(1/(n-i))%%1>0}

Try it online!

The code takes an integer as input and returns FALSE if the number is pleasing, and TRUE otherwise.

\$\endgroup\$
2
\$\begingroup\$

Python 3, 88 85 bytes

def f(n):p=n.rstrip(n[-1]);a=int(max(p));b=len(n)-len(p);return round(a**(1/b))**b==a

Ungolfed:

def is_pleasing_number( n ):
    prefix = n.rstrip(n[-1])
    a = int(max(prefix))
    b = len(n) - len(prefix)
    return round(a ** (1 / b)) ** b == a
  • The input argument is expected to be a digit string
  • The output is either True or False.
  • Similar to yet developed independently of Halvard’s answer but uses floating point arithmetic in a way that doesn't suffer from rounding errors until a ** (1 / b) is off by at least 0.5 from b√a which requires a value above 253 (or whatever floating point radix and mantissa length Python happens to use, see sys.float_info).
  • Can be modified trivially to still work with arbitrary number bases between 2 and 36.
\$\endgroup\$
  • \$\begingroup\$ @ovs: With a minor modification, yes. The function would have to take the base as an extra argument and pass it to the invocations of int and range. (At some point it would become more feasible to estimate the search range based ont a^(1/b) than to calculate large amounts of powers.) \$\endgroup\$ – David Foerster Dec 18 '17 at 18:11
2
\$\begingroup\$

C (gcc), 144 126 117 bytes

j,k,m;f(char*N){N+=j=strlen(N);k=~j;for(j=-1;m=N[j--]==N[j];);for(;k++<j;)m=fmax(N[k],m);j=!fmod(pow(m-48,1./~j),1);}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Ruby, 64 bytes

->a{!([a[/(\d)\1*$/].size,$`.chars.max]*?x!~/x1$|^2x[49]|^3x8/)}

Input as a string, returns true if:

  • B==1 (no need to check A)
  • A==4 and B==2
  • A==9 and B==2
  • A==8 and B==3

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Perl 6, 55 bytes

{m/(\d+?)((\d)$0*)$/;so any(^10)**$1.comb==$0.comb.max}

Try it online!

After the evaluation of the initial regex--which can only succeed if the input is a positive integer--$0 contains the initial part of the number, and $1 contains the trailing repeated digits.

The comb method without arguments, applied to a string, returns a list of the characters, which in numeric context evaluates to the length of the list. So $0.comb.max is the largest of the digits in the prefix, and $1.comb is the length of the suffix.

We then check whether any(^10) (ie, the or-junction of the numbers from 0-9), when raised to the power of the length of the suffix, is equal to the largest digit in the prefix. The so forces boolean evaluation of the resulting junction, which would otherwise be just fine on its own as a truthy value, but the challenge calls for just two distinct values to be returned.

\$\endgroup\$
  • \$\begingroup\$ This is late, but since the input is guaranteed to be an integer, the regex can use . instead of \d. \$\endgroup\$ – DLosc Apr 3 '18 at 23:21
1
\$\begingroup\$

Kotlin, 106 bytes

fun String.p()=split(Regex("(?=(.)\\1*$)")).let{Math.pow((it[0].max()?:'0')-'0'+.0,1.0/(it.size-1))}%1==.0

Output: true/false

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Add++, 21 bytes

L,BGubLV@¦+bMG1$/^1%!

Try it online!

It's been 3 and a half months, I hope I'm not ninja'ing anyone.

\$\endgroup\$
1
\$\begingroup\$

C# (.NET Core), 132 bytes

n=>{int A=0,B=1,s=1,i=n.Length-1;for(;i-->0;)if(n[i]==n[i+1]&s>0)B++;else{A=n[i]>A?n[i]:A;s=0;}return System.Math.Pow(A,1d/B)%1==0;}

Try it online!

Acknowledgements

-12 bytes thanks to @KevinCruijssen

DeGolfed

n=>{
    int A=0, // maximum digit
        B=1, // count of trailing identical numbers
        s=1, // 1 if dealing with trailing numbers, 0 otherwise
        i=n.Length-1;

    for(; i-- > 0;)
        if(n[i] == n[i+1] & s > 0)
            B++;
        else
        {
            A = n[i] > A? n[i] : A;
            s = 0;
        }

    return Math.Pow(A, 1d/B) % 1 == 0;
}
\$\endgroup\$
  • \$\begingroup\$ I know it's been a while, but i=n.Length-2;for(;i>=0;i--) can be golfed to i=n.Length-1;for(;i-->0;) and && can be golfed to &. \$\endgroup\$ – Kevin Cruijssen Apr 3 '18 at 11:54
  • \$\begingroup\$ Oh, and you can golf 6 more bytes by removing the using System; and using System.Math.Pow directly. \$\endgroup\$ – Kevin Cruijssen Apr 3 '18 at 11:57
  • \$\begingroup\$ One last thing. You currently take a list of characters, but it's also allowed to take a list of digits. In which case the -48 can be golfed for -3 bytes. \$\endgroup\$ – Kevin Cruijssen Apr 3 '18 at 12:13
1
\$\begingroup\$

Japt, 26 18 bytes

ó¶
o l
ñ o n qV v1

Try it online!


Takes input as a string, returns 1 for pleasing numbers, 0 otherwise.

Short explanation:

ó¶

Take the first input and split it by values where (x,y) => x===y is true. For example '41802000' to ['4','1','8','0','2','000'].

o l

Take the array from the first step, remove the last element and get its length, yielding B.

ñ o n qV v1

Find the largest element in the remaining array, yielding A, take it to the power 1/B and then return if the result is divisible by one.


First time working with Japt, very open to any recommendations.
Shaved off 8 bytes thanks to ETHproductions.

\$\endgroup\$
  • \$\begingroup\$ Hey, welcome to Japt! Sorry I missed your answers at first. A few tips: 1) You can use an auto-function to turn the first line into just ó¶. 2) Not sure why you have the v in the second line, as it just converts the string to lowercase and has no effect on the length ;-) 3) You can avoid the !(U on the last line by changing %1 to v1, which returns 1 if the subject is divisible by 1 or 0 otherwise. \$\endgroup\$ – ETHproductions Apr 6 '18 at 14:26
  • \$\begingroup\$ @ETHproductions Thanks a lot for your feedback, really appreciate it. I read about auto-functions before, but I still haven't quite gotten the hang of it, thanks for the example. I've incorporated the rest of your changes too, adding up to a total of 8 bytes lost. \$\endgroup\$ – Nit Apr 6 '18 at 14:38
0
\$\begingroup\$

Clojure, 168 bytes

(fn[x](let[y(reverse(vec x))z(count(take-while #(= %(first y))y))a(apply max(map #(-(int %)48)(drop z y)))b(Math/pow a(/ 1 z))](<(Math/abs(- b(Math/round b)))0.00001)))

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Charcoal, 33 bytes

≔ESιθ⊞υ⊟θW⁼§υ⁰§θ±¹⊞υ⊟θ¬﹪XI⌈θ∕¹Lυ¹

Try it online! Link is to verbose version of code. Outputs a - for pleasing numbers. Explanation:

≔ESιθ

Split the input q into characters.

⊞υ⊟θ

Remove the last character from q and push it to u (predefined to an empty list).

W⁼§υ⁰§θ±¹⊞υ⊟θ

Repeatly pop and push while the last character of q is the first character of u.

¬﹪XI⌈θ∕¹Lυ¹

Take the maximum digit of q and raise it to the power of the reciprocal of the length of u, then check whether the result is an integer.

\$\endgroup\$
0
\$\begingroup\$

Python 2, 91 85 bytes

s=`input()`;d=0
p=s.rstrip(s[-1])
exec"`d**(len(s)-len(p))`==max(p)>exit(1);d+=1;"*10

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Perl 5, 73 + 1 (-p) = 74 bytes

s/(.)\1*$//;$/=length$&;$_=(sort/./g)[-1];$q=$"++**$/while$q<$a;$_=$q==$a

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Java 8, 125 bytes

a->{int A=0,B=1,f=1,i=a.length-1;for(;i-->0;)if(a[i]==a[i+1]&f>0)B++;else{A=a[i]>A?a[i]:A;f=0;}return Math.pow(A,1d/B)%1==0;}

Port of @Ayb4btu's C# .NET answer.

Try it online.

Explanation:

a->{                       // Method with digit-array parameter and boolean return-type
  int A=0,                 //  Maximum digit `A` as specified in the challenge description
      B=1,                 //  `B` as specified in the challenge description
      f=1,                 //  Flag-integer, starting at 1
      i=a.length-1;        //  Index integer `i`
  for(;i-->0;)             //  Loop `i` backwards over the digits (excluding the last)
    if(a[i]==a[i+1]        //   If the current and next digits are the same,
       &f>0)               //   and the flag is still 1
      B++;                 //    Increase `B` by 1
    else{                  //   Else:
      A=a[i]>A?            //    If the current digit is larger than `A` 
         a[i]              //     Replace `A` with the current digit
        :                  //    Else:
         A;                //     Leave `A` the same
      f=0;}                //    Set the flag-integer to 0
  return Math.pow(A,1d/B)  //  Return if `A` ^ (1/`B`)
    %1==0;}                //  is an exact integer
\$\endgroup\$
0
\$\begingroup\$

Pip, 32 22 21 bytes

'.N(#a-#Ya<|a@v)RTMXy

Uses 1 for falsey and 0 for truthy, saving a byte. Try it online!

\$\endgroup\$
0
\$\begingroup\$

Pyth, 29 bytes

JezWqezJ=Pz=hZ)K@sh.MsZzZqKsK

Test suite

Python 3 translation:
Z=0
z=input()
J=z[-1]
while z[-1]==J:
    z=z[:-1]
    Z+=1
K=max(map(int,z))**(1/Z)
print(K==int(K))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.