18
\$\begingroup\$

Take a look at the sevens multiplication table from 7×0 to 7×9:

0, 7, 14, 21, 28, 35, 42, 49, 56, 63 

If we just look at the digits in the one's place we get a permutation of the digits 0 through 9:

0, 7, 4, 1, 8, 5, 2, 9, 6, 3 

Consider taking some positive decimal integer N and replacing each digit D in N with the the digit in the one's place of 7×D.

For example, 15209 becomes 75403 because 1 maps to 7, 5 maps to 5, 2 maps to 4, 0 maps to 0, and 9 maps to 3.

Now lets repeat this process with this new decimal integer until we see a cycle, i.e. until an integer we've already seen comes up.

For example, with 15209 we get the cycle

15209 -> 75403 -> 95801 -> 35607 -> 15209 -> repeats... ^ | cycle restarts here 

As another example, 505 has the short cycle

505 -> 505 -> repeats... ^ | cycle restarts here 

It turns out that for any N these cycles will always contain exactly 1 or 4 distinct integers. (I'll leave it to you to figure out why that is.) What's interesting is that if you sum all the distinct integer in a cycle, you almost always get a decimal integer that only consists of 2's and 0's.

For example, 15209 + 75403 + 95801 + 35607 = 222020.

N = 505 is one of the exceptions. The only integer in the cycle is 505 so the total sum is 505 itself.

Here are the sums of the cycles for N = 1 to 60:

N sum 1 20 2 20 3 20 4 20 5 5 6 20 7 20 8 20 9 20 10 200 11 220 12 220 13 220 14 220 15 220 16 220 17 220 18 220 19 220 20 200 21 220 22 220 23 220 24 220 25 220 26 220 27 220 28 220 29 220 30 200 31 220 32 220 33 220 34 220 35 220 36 220 37 220 38 220 39 220 40 200 41 220 42 220 43 220 44 220 45 220 46 220 47 220 48 220 49 220 50 50 51 220 52 220 53 220 54 220 55 55 56 220 57 220 58 220 59 220 60 200

We'll call this the Seven's Cycle Sum Sequence.

Challenge

Write a program or function that takes in a positive decimal integer N and prints or returns, in decimal, the corresponding term of the Seven's Cycle Sum Sequence.

For example, if the input is 95801, the output should be 222020. If the input is 505, the output should be 505. If the input is 54, the output should be 220.

The shortest code in bytes wins.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Of course, if you take the numbers from the one-cycles and multiply them by four, you'll find that all of them give numbers whose only digits are 2 and 0. \$\endgroup\$ Commented Dec 7, 2015 at 9:30

10 Answers 10

5
\$\begingroup\$

Python 2, 69 bytes

lambda n:[''.join('02'[x>'0']for x in`n`)+'0',n][set(`n`)<=set('05')] 

The function is simple to describe:

  • If n consists of only 0's and 5's, output it unchanged.
  • Otherwise, replace each digit of n with 2, except 0 stays 0, and tack on a 0 to the end.

The golfing can be improved, I'm mostly posting to share the method. A language with native regex should allow a short solution.

An alternative statement of the function is

  • In n, replace each digit with a 5, except 0 stays as 0
  • If this changed n (it had a digit other than 0 or 5), multiply the result by 4
\$\endgroup\$
4
\$\begingroup\$

Python 2, 63 bytes

lambda s:s.strip('05')and''.join(`(c>'0')*2`for c in s)+'0'or s 

Input argument is expected to be a string.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Wow, I had no idea strip behaved this way. \$\endgroup\$ Commented Dec 7, 2015 at 6:20
  • \$\begingroup\$ Come on, type conversions (string &harr; number) are a substantial part of the fun (i.e. code length ;o)! \$\endgroup\$ Commented Dec 8, 2015 at 10:48
4
\$\begingroup\$

CJam, 16 bytes

Using the same algorithm as everyone else:

r_50s-{:~2fe&0}& 

Test suite. (Generates all results from 1 to the input.)

Explanation

r_ e# Read input and duplicate 50s e# Push the string "50". - e# Remove all '5' and '0' characters from the input. { e# If any characters remained in the input... :~ e# Evaluate each digit character to turn it into an integer. 2fe& e# Map (&& 2) over the list. Due to short-circuiting, zeros remain zeros and e# everything else becomes 2. 0 e# Push a trailing zero. }& 
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 54 51 bytes

Using xnor's method:

n=>/[^05]/.test(n)?`${n}0`.replace(/./g,d=>+d&&2):n 

Saved 3 bytes thanks to @charlie!

Explanation

n=> (s=n+"").match`[^05]` // if there are any digits which aren't 5 or 0 ?s.replace(/\d/g,d=>+d&&2)+0 // replace every digit except 0 with 2 then add a 0 :s // else return the input unchanged 

Test

<input type="number" id="input" value="0" oninput='result.textContent=( n=>(s=n+"").match`[^05]`?s.replace(/\d/g,d=>+d&&2)+0:s )(+input.value)' /> <pre id="result"></pre>

Naive method, 102 bytes

n=>(c=x=>~r.indexOf(x+=m="")?eval(r.join`+`):[...r[++i]=x].map(d=>m+="0741852963"[d])&&c(m))(n,i=r=[]) 
n=> (c=x=> // c = recursive function ~r.indexOf( // if we have calculated this number before x+=m="")? // cast x to a string, m = calculated result eval(r.join`+`): // return the sum of all the calculated numbers [...r[++i]=x].map(d=> // else add x to the list of calculated numbers m+="0741852963"[d] // map each digit of x to the "seven" digits )&&c(m) // calculate the value of the result )(n,i=r=[]) // r = array of previously calculated values 

<input type="number" id="input" value="0" oninput='result.textContent=( n=>(c=x=>~r.indexOf(x+=m="")?eval(r.join`+`):[...r[++i]=x].map(d=>m+="0741852963"[d])&&c(m))(n,i=r=[]) )(+input.value)' /> <pre id="result"></pre>

\$\endgroup\$
4
  • \$\begingroup\$ 51 bytes: n=>/[^05]/.test(n)?`${n}0`.replace(/./g,d=>+d&&2):n \$\endgroup\$ Commented Dec 7, 2015 at 19:57
  • 1
    \$\begingroup\$ 40 bytes: n=>n-(s=`${n}`.replace(/[^0]/g,5))?s*4:n \$\endgroup\$ Commented Dec 8, 2015 at 9:55
  • 1
    \$\begingroup\$ @charlie Wow, that s*4 trick is awesome! I reckon you should post this as a separate answer because the method is different enough and it's so much shorter than mine. :) \$\endgroup\$ Commented Dec 8, 2015 at 10:02
  • \$\begingroup\$ ok, i humbly will ;o) \$\endgroup\$ Commented Dec 8, 2015 at 10:10
2
\$\begingroup\$

Mathematica, 83 77 60 characters

Tr@Union@NestList[FromDigits@Mod[7IntegerDigits@#,10]&,#,4]& 

Ungolfed

Tr@ Union@ NestList[ FromDigits@Mod[7 IntegerDigits@#, 10] &, #, 4 ] & 
\$\endgroup\$
0
2
\$\begingroup\$

JavaScript (ES5), 40 bytes

n=>(s=`${n}`.replace(/[^0]/g,5))^n?s*4:n 

It's an evolution of the user81655's solution, using the alternative approach described by xnor.

Explanation

Sum of a non-zero digit in the 4-cycle is always 20, since the digit cycles either through 1→7→9→3, or 2→4→8→6, or 5→5→5→5. So replacing every such a digit with 5 doesn't change the sum.

That replacement action is reused to distinguish the 4-cycle from 1-cycle — if the replacement result is different from the input, then it's a 4-cycle, otherwise it's a 1-cycle.

N.B.: The template string `${n}` is just for readability, (n+'') has the same length.

\$\endgroup\$
1
  • \$\begingroup\$ no regexp -- 47 bytes: n=>(s=[...`${n}`].map(d=>+d&&5).join``)^n?s*4:n \$\endgroup\$ Commented Dec 8, 2015 at 16:58
1
\$\begingroup\$

Pyth, 14 bytes

s.uieM*R7jNTTQ 

Not sure, why everybody determines the result by looking at patterns in the numbers. Simply doing the process, calculating all numbers of the circle and summing them up is shorter. At least in Pyth ;-)

Try it online: Demonstration or Test Suite

Btw, this is my 200th code-golf answer. So this post earns me the Gold code-golf badge.

Explanation:

s.uieM*R7jNTTQ implicit: Q = input number .u Q apply the following expression to N=Q until it reaches a circle jNT convert N to base 10 *R7 multiply each digit with 7 eM and perform modulo 10 for each number i T convert digits from base 10 to a number update N .u returns the list of all intermediate results of N, so we have now all numbers of the circle s sum them up 
\$\endgroup\$
1
  • \$\begingroup\$ Code... wait for it... golf! :) Congrats, and nice use of .u \$\endgroup\$ Commented Dec 9, 2015 at 20:12
0
\$\begingroup\$

sed, 26 bytes

/[^05]/{s/[^0]/2/g;s/$/0/}

(Another take on the "replace by 2's" approach.)

Examples

echo '500' | sed '/[^05]/{s/[^0]/2/g;s/$/0/}'500

echo '501' | sed '/[^05]/{s/[^0]/2/g;s/$/0/}'2020

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

Perl 6,  68 55 53 36  33 bytes

{[+] $^a,{[~] $^b.comb.map: {'0741852963'.comb[$_]}}...^{$++*?/$a/}} # 68 
{$_=@=$_.comb;[~] (@$_,(|.map(2*?+*),0))[$_⊈qw<0 5>]} # 55 
{[~] ($_=@=$_.comb)⊆qw<0 5>??@$_!!(|.map(2*?+*),0)} # 53 
{/^<[05]>+$/??$_!!S:g/./{2*?+$/}/~0} # 36 

{m/^<[05]>+$/||S:g/./{2*?+$/}/~0} # 33 

This is definitely the wrong way to do this, if the number is consists only of 5s and 0s it will return a Match object, otherwise it replaces everything but 0 with a 2, and append a 0 to the end.
( The Match object will behave like a number if you use it as one )

Though since it is doing it wrong, it makes it easy to point out the rare numbers by calling the gist method.

usage:

# give it a name my &code = {...} .say for (0..60,505,15209).flat.map({ code($_).gist.fmt: '%4s' }).rotor(1,10 xx 6,:partial) ( 「0」) ( 20 20 20 20 「5」 20 20 20 20 200) ( 220 220 220 220 220 220 220 220 220 200) ( 220 220 220 220 220 220 220 220 220 200) ( 220 220 220 220 220 220 220 220 220 200) ( 220 220 220 220 220 220 220 220 220 「50」) ( 220 220 220 220 「55」 220 220 220 220 200) (「505」) (222020) 
\$\endgroup\$
0
\$\begingroup\$

Jelly, 9 bytes

D×7%⁵ƊƬḌS 

Try it online!

How it works

D×7%⁵ƊƬḌS - Main link. Takes an integer n on the left D - Convert to digits ƊƬ - Repeat the following until a value is repeated and collect all intermediate values: ×7 - Multiply each digit by 7 %⁵ - Take the ones digit Ḍ - Convert each list of digits back to a number S - Take the sum 
\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.