19
\$\begingroup\$

Given a number n and an upper limit l list the numbers that can be created by multiplying two or more numbers consisting of only sevens of length n or less that are less than l. A161145 is close to this challenge, however, you will NOT be including the 7, 77, 777, 7777, 77777, etc..

Examples

n=anything, l<49 would result in:

[]

n=1, l=49 would result in:

7*7=49

f(1,49)=[49]

n=1, l=343 would result in:

7*7   =49
7*7*7 =343

f(1,343)=[49,343]

n=2,l=6000 would result in:

7*7    =49
7*7*7  =343
7*7*7*7=2401
7*77   =539
7*7*77 =3773
77*77  =5929

f(2,6000)=[49,343,539,2401,3773,5929]

n=3, l=604000 would result in:

[49, 343, 539, 2401, 3773, 5439, 5929, 16807, 26411, 38073, 41503, 59829, 117649, 184877, 266511, 290521, 418803, 456533, 603729]

Etc...

Rules

  1. You do not have to output intermediate steps, this was done for clarity.
  2. Output can be as an array or separated by any character (even newlines).
  3. Output must be in numerical order, lowest to highest.
  4. To make the title relevant, highest n that must be handled is n=77 (if you can't handle that high, note why - language restrictions are acceptable, laziness is not). This limitation is to hinder those looking to build the entire superset in memory.
  5. If TIO cannot run n=77 for your code, explain what specs were required to achieve n=77.
  6. For a product to be valid it must consist of at least 2 numbers.
  7. This is lowest byte-count will be deemed victorious.
  8. You may choose the list to contain items less than l or less than/equal to l.
  9. BONUS: If your code is exactly 77 bytes, kudos from me; worthless, I know.
\$\endgroup\$
5
  • \$\begingroup\$ I'm having trouble parsing "list the numbers that can be created by multiplying two or more numbers consisting of only sevens of length n or less that are less than l" \$\endgroup\$
    – xnor
    Commented Apr 25, 2017 at 22:14
  • \$\begingroup\$ Is it acceptable to have some numbers output more than once? \$\endgroup\$ Commented Apr 25, 2017 at 23:19
  • \$\begingroup\$ Rule 5 is pretty pointless, will any code run given n=77 and l=7**7**7, for example? \$\endgroup\$ Commented Apr 26, 2017 at 0:53
  • 1
    \$\begingroup\$ Can we assume that the result will not be empty? \$\endgroup\$
    – Titus
    Commented Apr 26, 2017 at 1:41
  • \$\begingroup\$ @JonathanAllan true. \$\endgroup\$ Commented Apr 26, 2017 at 15:08

12 Answers 12

7
\$\begingroup\$

Jelly, 21 20 19 18 bytes

R7ẋḌµ;ŒċP€⁹f€FµÐLḟ

Note that the output doesn't match the OP's. I've left a comment.

Try it online!

How it works

R7ẋḌµ;ŒċP€⁹f€FµÐLḟ  Main link. Left argument: n. Right argument: l

R                   Range; yield [1, ..., n].
 7ẋ                 Times; yield [[7], ..., [7] * n].
   Ḍ                Undecimal; yield s := [7, 77, ...].
    µ         µÐL   Begin a new chain with argument s and call the chain between 
                    until the results no longer chain.
                    Return the last unique result.
      Œċ            Combinations; return all unordered pairs in integers in the
                    return value.
     ;              Concatenate the return value and its pairs.
        P€          Take the product of each individual integer and each pair in
                    the result.
          ⁹f€       Filter each; for each j in [1, ..., l], intersect [j] with the
                    array of products. The result is sorted and contains no 
                    duplicates.
                 ḟ  Filterfalse; remove the elements of s from the result.
\$\endgroup\$
0
6
\$\begingroup\$

Python 2, 116 113 109 bytes

n,l=input()
r=t={1}
exec't|={10**n/9*7};n-=n>1;r=r|{x*y for x in r for y in t if l/x/y};'*l
print sorted(r-t)

Note that TIO doesn't have enough memory for the last test case.

Try it online!

\$\endgroup\$
4
\$\begingroup\$

JavaScript (ES6), 103 101 bytes

Takes input in currying syntax (n)(l).

n=>l=>(a=[],g=(n,m,p,i)=>(p>l||g(n,m,(a[i>1?p:a]=p)*m,-~i),--n?g(n,m+7,p,i):a.filter(n=>n)))(n,'7',1)

Test cases

The last test case may take a few seconds to complete.

let f =

n=>l=>(a=[],g=(n,m,p,i)=>(p>l||g(n,m,(a[i>1?p:a]=p)*m,-~i),--n?g(n,m+7,p,i):a.filter(n=>n)))(n,'7',1)

console.log(f(1)(49))
console.log(f(1)(343))
console.log(f(2)(6000))
console.log(f(3)(604000))

\$\endgroup\$
4
\$\begingroup\$

PHP, 142 Bytes

$r=[];for([,$n,$l]=$argv;$n--;)f($v[]=$z.=7);function f($t){global$v,$l,$r;while($c=$t*$v[+$i++])$l<$c?:f($c)&$r[$c]=$c;}sort($r);print_r($r);

-5 Bytes removing $r=[]; and replace sort($r); with @sort($r);

Online Version

Expanded

A recursive function make all permutations including the limit

$r=[];
for([,$n,$l]=$argv;$n--;)
  f($v[]=$z.=7);
function f($t){
    global$v,$l,$r;
    while($c=$t*$v[+$i++])
      $l<$c?:f($c)&$r[$c]=$c;
}
sort($r);
print_r($r);

PHP, 145 Bytes

for([,$n,$l]=$argv;$n;)$t[]=str_pad(7,$n--,7);for(;$l>=$i+=49;$v>1?:$u[]=$r)for($v=$i,$r=!$c=0;$d=$t[$c];)$v%$d?$c++:($v/=$d)&$r*=$d;print_r($u);

Expanded

a loop till including the limit check every value that is divisible by 49

for([,$n,$l]=$argv;$n;)
  $t[]=str_pad(7,$n--,7);
for(;$l>=$v=$i+=49;$v>1?:$u[]=$r)
  for($r=!$c=0;$d=$t[$c];)
    $v%$d?$c++:($v/=$d)&$r*=$d;
print_r($u);

Online Version

a few bytes more and an associative array can be created key the number and as value an array of the used sevens

for([,$n,$l]=$argv;$n;)
  $t[]=str_pad(7,$n--,7);
for(;$l>=$v=$i+=49;$v>1?:$u[array_product($r)]=$r)
  for($r=[],$c=0;$d=$t[$c];)
    $v%$d?$c++:($v/=$d)&$r[]=$d;
print_r($u);

Online Version

\$\endgroup\$
10
  • \$\begingroup\$ while($c=$t*$v[+$i++])$l<$c?f($c)&$r[$c]=$c; saves 3 bytes; but it should be $l<=$c. $r?sort($r)&print_r($r):0; instead of $r=[]; saves one. \$\endgroup\$
    – Titus
    Commented Apr 26, 2017 at 1:52
  • 1
    \$\begingroup\$ $z.=7; is 5 bytes shorter than $z=$z*10+7;. \$\endgroup\$
    – Titus
    Commented Apr 26, 2017 at 2:01
  • \$\begingroup\$ and @ is another 4 bytes shorter than $r?...:0;. (Thanks @Christoph) \$\endgroup\$
    – Titus
    Commented Apr 26, 2017 at 14:02
  • \$\begingroup\$ @Titus Why should it be $l<=$c ? It seems yesterday was not my day for the $z.=7 and the additional 2 Bytes that I have found. I am thinking first over your other two suggestions. You miss the : in the while loop \$\endgroup\$ Commented Apr 26, 2017 at 14:52
  • \$\begingroup\$ I´ve asked the OP to clarify. In the description he talks about results that are less than l, in his examples they are less than or equal. Depending on the clarification, $c>$l||.../$c>$l?:... or $c<$l&&... are shortest. \$\endgroup\$
    – Titus
    Commented Apr 26, 2017 at 15:04
4
\$\begingroup\$

Ruby, 89 86 bytes

A recursive solution.

-3 bytes by remembering that anything times 0 is 0.

f=->n,l,b=1{n*l>0?(f[n,l/k=eval(?7*n),b*k]+f[n-1,l,b]+(b>1&&l>=k ?[k*b]:[])).sort: []}

Try it online!

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

Pyth, 22 bytes

JsM._*\7Eu@s*LR+JGJSQJ

JsM._*\7E
        E               second input
     *\7                repeat "7" as many times as the above
   ._                   all prefixes of above
 sM                     convert each to integer
J                       store list as J

         u@s*LR+JGJSQJ
         u              repeat the following until results not unique
                     J  starting from G = J
                        at each iteration, G is the current value
               +JG      append G to J
                  J     J
            *LR         multiply the elements of the above two, vectorizing each
           s            flatten list
          @        SQ   intersect with [1,2,3,...,first input]
                        this takes elements from [1,2,3,...,first input] and
                        check if each element is in the previous list
                        which ensures the result is sorted and unique

Try it online!

Specs

  • Input: l[newline]n
  • Output: array containing the sorted result
\$\endgroup\$
3
\$\begingroup\$

PHP, 128 125 130 129 127 123 bytes

will work up to 22 7s but will round larger values (7**23 is floating point on a 64 bit machine).

3 bytes saved by Jörg, 3 by me, 5 4 1 added to avoid warning for empty results.

for([,$c,$z]=$argv,$n=$c+1;$c<$z;$p<$z&&$r[$p]=$p)for($b=$c+=$p=1;$b|0;$b/=$n)$p*=str_pad(7,$b%$n,7);@sort($r);print_r($r);

takes input from command line arguments; run with -nr or try it online.

breakdown

for([,$c,$z]=$argv,$n=$c+1;         # $z=L, $n=N+1
    $c<$z;                          # loop $c from N to L-1:
    $p<$z&&$r[$p]=$p                    # 2. if product is < L, add to array
)                                       #    (key=val to avoid duplicates)
    for($b=$c+=$p=1;$b|0;$b/=$n)        # 1. loop $b through ++$c as base-N+1 number
        $p*=str_pad(7,$b%$n,7);             # take each base-N+1 digit as length
                                            # for a streak of 7s as factor
        // (str_pad is 1 byte shorter than str_repeat and saves 3 by ensuring positive $p)
@sort($r);                          # sort array (muted to avoid warning for empty result)
print_r($r);                        # print array
\$\endgroup\$
5
  • 1
    \$\begingroup\$ for([,$c,$z]=$argv,$n=1+$c;$c<$z; instead of for($n=1+$c=$argv[1];$c<$z=$argv[2]; \$\endgroup\$ Commented Apr 26, 2017 at 0:28
  • 1
    \$\begingroup\$ Use @ instead of $r&& to suppress the warning? $p<$z&&$r[$p]=$p \$\endgroup\$
    – Christoph
    Commented Apr 26, 2017 at 9:08
  • \$\begingroup\$ I just noticed it should be $p>$z?:$r[$p]=$p from example n=1, l=343 it is clear that l should be included. Therefore no savings there when using $p>$z||$r[$p]=$p or $p>$z?:$r[$p]=$p. \$\endgroup\$
    – Christoph
    Commented Apr 26, 2017 at 9:30
  • 1
    \$\begingroup\$ @Christoph I asked the OP to clarify. Thanks for reminding me of @; will edit when the OP replies. \$\endgroup\$
    – Titus
    Commented Apr 26, 2017 at 14:03
  • 1
    \$\begingroup\$ @Christoph both seem to be ok; and it doesn´t really matter wether $p>$z|| or $p<$z&&. I´ll stick with the description. \$\endgroup\$
    – Titus
    Commented Apr 26, 2017 at 21:23
3
\$\begingroup\$

Brachylog, 28 bytes

h>.ḋ{p~c×ᵐ{=h7&l}ᵐobt≤~t?∧!}

There's a lot of scope for improvement in the language itself, here; quite a few things I wrote look like they'd be obviously improvable with some changes to the language's design. This is the shortest way I've found with the current version. I may well make some suggestions for Brachylog which would make this program more efficient, shorter, and more readable.

Very, very slow; TIO times out even on the simplest possible nontrivial answer, so there's not much point in providing a TIO link. I've verified this program by running it locally.

This is a function (not a full program), whose output is a generator (as opposed to a list). Add .w⊥ to the end of the function if you want to see all outputs, rather than just the first. (Note that this doesn't really matter in practice, because as the program is too slow for TIO anyway, you have to run it locally, and the local Brachylog interpreter runs in a REPL which can describe a generator just fine.)

Explanation

h>.ḋ{p~c×ᵐ{=h7&l}ᵐobt≤~t?∧!}
  .                           The desired output is
h>                            a number less than the first input
   ḋ p                        such that taking its prime factors in some order,
      ~c                      partitioning them,
        ×ᵐ                    and taking the product of each partition
          {     }ᵐ            produces a number for which each digit
           =h7                is composed only of 7s
              &l              and for which the lengths of those numbers
                  o           are in sorted order
                    t         and the last element
                   b          (which is not also the first element)
                     ≤        is less than or equal to
                      ~t?     the last input.
                         ∧    (Delete an unwanted implicit constraint.)
   ḋ{                     !}  Output each number only once.
\$\endgroup\$
2
\$\begingroup\$

Bash + GNU utilities, 108

seq -f3o%gp $2|dc|sed -r "/0|1{$1}/d;s/./&7/g;s/1//g;s/2/*/g;/[*]/!d;s/^/a=7/;s/$/;if(a<=$2)a;/"|bc|sort -un

Try it online. TIO takes about a minute for the last testcase. My results match @Dennis's.

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

05AB1E, 19 bytes

L7×1¸ì©IF®âPD²‹Ïê®K

Try it online!

Explanation

Very inefficient. TIO link performs ceil(l^(1/7)) iterations instead of the l iterations used in the golfed version to easier test large testcases.

L7×                   # create the list ['7', '77', '777' ...] 
                      # with the final item having n 7's 
   1¸ì©               # prepend a 1 and store a copy in register
       IF             # l times do:
         ®â           # cartesian product between current list and the list in register 
           P          # product of each sublist
            D²‹Ï      # keep only numbers smaller than l
                ê     # remove duplicates and sort
                 ®K   # remove 1, 7, 77, 777 ... from the list
\$\endgroup\$
4
  • \$\begingroup\$ $L7ׂ˜ - tried to get 5 bytes, couldn't. \$\endgroup\$ Commented Apr 26, 2017 at 15:45
  • \$\begingroup\$ @carusocomputing: Yeah, I feel like 6 bytes is too much, but I really can't see a shorter way. I was hoping you'd school me with a shorter way ;) \$\endgroup\$
    – Emigna
    Commented Apr 26, 2017 at 15:47
  • \$\begingroup\$ I was thinking .p or .s too, but even those seem longer. I accidentally hit 'refresh' on the TIO page with my example implementation instead of run, deleted it from existence. I think it was 26 though. \$\endgroup\$ Commented Apr 26, 2017 at 16:32
  • 1
    \$\begingroup\$ @carusocomputing: That's why you should always press the link button regularly. Don't loose anything by refreshing or rebooting the computer. A bit annoying to loose history though :) \$\endgroup\$
    – Emigna
    Commented Apr 26, 2017 at 16:36
1
\$\begingroup\$

Pyth -- 57 51 49 42 bytes

FY}2eQKYJv*\7hQWJIqYJBW!%KJ=/KJ)=/JT)Iq1KY

Try it

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Welcome to PPCG! There are many shortcuts available, which can cut down your code by a lot of bytes. You can come to our chatroom and ping me if you want to know more. \$\endgroup\$
    – Leaky Nun
    Commented Apr 26, 2017 at 1:49
  • 1
    \$\begingroup\$ Unfortunately, your current program does not generate the correct results, namely that it includes 7 and 77 for your current input. \$\endgroup\$
    – Leaky Nun
    Commented Apr 26, 2017 at 1:53
  • 1
    \$\begingroup\$ Ways to cut down bytes include: using m instead of F or V etc. (functional programming vs. execution control); using hQ instead of @Q0; using eQ instead of @Q1; using i*hQ]7T instead of the long for-loop to generate 777...7. \$\endgroup\$
    – Leaky Nun
    Commented Apr 26, 2017 at 1:58
  • \$\begingroup\$ @LeakyNun Thanks much for the suggestions and the chatroom link. Also, I fixed it. \$\endgroup\$
    – Maria
    Commented Apr 26, 2017 at 2:23
0
\$\begingroup\$

JavaScript (Node.js), 94 91 88 bytes

n=>l=>(X=[]).filter(g=(i,j=1,k)=>j>l|i[n]||(X[g(i+7,j,k)|g(i,j*i,-~k),k>1&&j]=j),l=g`7`)

Try it online!

n=>l=>         // input
(X=[]).filter( // X stores index=results
g=(i,j=1,k)=>  // recurse             Reuse of g for filter:
j>l|i[n]||     // out of range        49>1|49[n] (true)
(X[g(i+7,j,k)|g(i,j*i,-~k),k>1&&j]=j)
               // k<=1: X[false]=j, ignored
               // k>1: X[j]=j
,l=g`7`)       // First call [0/1]|[0/1]||1 ==1
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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