Podziel bity!

17

Definiujemy jako listę odrębnych potęg które sumują się do . Na przykład .2 x V ( 35 ) = [ 32 , 2 , 1 ]V(x)2xV(35)=[32,2,1]

Zgodnie z konwencją, moce są tutaj sortowane od najwyższych do najniższych. Ale nie wpływa to na logikę wyzwania ani oczekiwane rozwiązania.

Zadanie

Biorąc pod uwagę półpierwszą literę , zamień każdy termin w inną listę potęg które sumują się do tego terminu, w taki sposób, że suma wszystkich powstałych podlist stanowi dokładne pokrycie macierzy zdefiniowanej jako:V ( N ) 2 M.NV(N)2M

Mi,j=V(P)i×V(Q)j

gdzie i są głównymi czynnikami .Q NPQN

Jest to o wiele łatwiejsze do zrozumienia na niektórych przykładach.

Przykład 1

Dla mamy:N=21

  • V(N)=[16,4,1]
  • P=7 iV(P)=[4,2,1]
  • Q=3 iV(Q)=[2,1]
  • M=(842421)

Aby zmienić w dokładną osłonę , możemy podzielić na i na , podczas gdy pozostanie niezmienione. Możliwe wyjście to:V(N)M168+4+442+21

[[8,4,4],[2,2],[1]]

Innym ważnym wyjściem jest:

[[8,4,2,2],[4],[1]]

Przykład nr 2

Dla mamy:N=851

  • V(N)=[512,256,64,16,2,1]
  • P=37 iV(P)=[32,4,1]
  • Q=23 and V(Q)=[16,4,2,1]
  • M=(512641612816464823241)

A possible output is:

[[512],[128,64,64],[32,16,16],[8,4,4],[2],[1]]

Rules

  • Because factorizing N is not the main part of the challenge, you may alternately take P and Q as input.
  • When several possible solutions exist, you may either return just one of them or all of them.
  • You may alternately return the exponents of the powers (e.g. [[3,2,2],[1,1],[0]] instead of [[8,4,4],[2,2],[1]]).
  • The order of the sub-lists doesn't matter, nor does the order of the terms in each sub-list.
  • For some semiprimes, you won't have to split any term because V(N) already is a perfect cover of M (see A235040). But you still have to return a list of (singleton) lists such as [[8],[4],[2],[1]] for N=15.
  • This is !

Test cases

 Input | Possible output
-------+-----------------------------------------------------------------------------
 9     | [ [ 4, 2, 2 ], [ 1 ] ]
 15    | [ [ 8 ], [ 4 ], [ 2 ], [ 1 ] ]
 21    | [ [ 8, 4, 4 ], [ 2, 2 ], [ 1 ] ]
 51    | [ [ 32 ], [ 16 ], [ 2 ], [ 1 ] ]
 129   | [ [ 64, 32, 16, 8, 4, 2, 2 ], [ 1 ] ]
 159   | [ [ 64, 32, 32 ], [ 16 ], [ 8 ], [ 4 ], [ 2 ], [ 1 ] ]
 161   | [ [ 64, 32, 16, 16 ], [ 8, 8, 4, 4, 4, 2, 2 ], [ 1 ] ]
 201   | [ [ 128 ], [ 64 ], [ 4, 2, 2 ], [ 1 ] ]
 403   | [ [ 128, 64, 64 ], [ 32, 32, 16, 16, 16, 8, 8 ], [ 8, 4, 4 ], [ 2 ], [ 1 ] ]
 851   | [ [ 512 ], [ 128, 64, 64 ], [ 32, 16, 16 ], [ 8, 4, 4 ], [ 2 ], [ 1 ] ]
 2307  | [ [ 1024, 512, 512 ], [ 256 ], [ 2 ], [ 1 ] ]
Arnauld
źródło
can we take P and Q instead of N?
ngn
@ngn I'm going to say yes, because factorizing N is not the main part of the challenge.
Arnauld
1
May we return the output flattened?
Erik the Outgolfer
@EriktheOutgolfer ... The output flattened is just a partition of the input (1+2+2+4=9, for example). I don't think it should be allowed
Mr. Xcoder
@EriktheOutgolfer I don't think it could be unambiguous this way, as the last term of a sub-list may be the same as the first term of the next one.
Arnauld

Odpowiedzi:

4

K (ngn/k), 66 63 bytes

{(&1,-1_~^(+\*|a)?+\b)_b:b@>b:,/*/:/2#a:{|*/'(&|2\x)#'2}'x,*/x}

Try it online!

accepts (P;Q) instead of N

algorithm:

  • compute A as the partial sums of V(P*Q)

  • multiply each V(P) with each V(Q), sort the products in descending order (let's call that R), and compute their partial sums B

  • find the positions of those elements in B that also occur in A; cut R right after those positions

ngn
źródło
3

Jelly, 24 bytes

BṚT’2*
Ç€×þ/FṢŒṖ§⁼Ç}ɗƇPḢ

A monadic link accepting a list of two integers [P, Q] which yields one possible list of lists as described in the question.

Try it online! (footer prints a string representation to show the list as it really is)

Or see the test-suite (taking a list of N and reordering results to be like those in the question)

How?

We may always slice up the elements of M from lowest up, greedily (either there is a 1 in M or we had an input of 4, when M=[[4]]) in order to find a solution.

Note: the code collects all (one!) such solutions in a list and then takes the head (only) result - i.e. the final head is necessary as the partitions are not of all possible orderings.

BṚT’2* - Link 1, powers of 2 that sum to N: integer, N    e.g. 105
B      - binary                                                [1,1,0,1,0,0,1]
 Ṛ     - reverse                                               [1,0,0,1,0,1,1]
  T    - truthy indices                                        [1,4,6,7]
   ’   - decrement                                             [0,3,5,6]
    2  - literal two                                           2
     * - exponentiate                                          [1,8,32,64]

Ç€×þ/FṢŒṖ§⁼Ç}ɗƇPḢ - Main Link: list of two integers, [P,Q]
Ç€                - call last Link (1) as a monad for €ach
    /             - reduce with:
   þ              -   table with:
  ×               -     multiplication
     F            - flatten
      Ṣ           - sort
       ŒṖ         - all partitions
              Ƈ   - filter keep if:
             ɗ    -   last three links as a dyad:
         §        -     sum each
            }     -     use right...
               P  -       ...value: product (i.e. P×Q)
           Ç      -       ...do: call last Link (1) as a monad
          ⁼       -     equal? (non-vectorising so "all equal?")
                Ḣ - head
Jonathan Allan
źródło
3

Python 2, 261 233 232 231 bytes

g=lambda n,r=[],i=1:n and g(n/2,[i]*(n&1)+r,i*2)or r
def f(p,q):
 V=[[v]for v in g(p*q)];i=j=0
 for m in sorted(-a*b for a in g(p)for b in g(q)):
	v=V[i]
	while-m<v[j]:v[j:j+1]=[v[j]/2]*2
	i,j=[i+1,i,0,j+1][j+1<len(v)::2]
 return V

Try it online!

1 byte from Jo King; and another 1 byte due to Kevin Cruijssen.

Takes as input p,q. Pursues the greedy algorithm.

Chas Brown
źródło
-k-1 can be ~k.
Jonathan Frech
The i,j assignment can be i,j=[i+1,i,0,j+1][j+1<len(v)::2] for -1 byte
Jo King
@Jo King: Hahaha! That is twisted!
Chas Brown,
while v[j]>-m can be while-m<v[j]
Kevin Cruijssen
@Kevin Cruijssen: Yes, indeed. Thx!
Chas Brown
2

Jelly, 41 bytes

Œṗl2ĊƑ$Ƈ
PÇIP$ƇṪÇ€Œpµ³ÇIP$ƇṪƊ€ŒpZPṢ⁼FṢ$µƇ

Try it online!

Should probably be much shorter (some parts feel very repetitive; especially ÇIP$Ƈ, but I don't know how to golf it). Explanation to come after further golfing. Returns all possible solutions in case multiple exist and takes input as [P,Q].

Mr. Xcoder
źródło
Not that it is a problem, but it's not exactly fast, is it? :)
Arnauld
@Arnauld It uses roughly 3 integer partition functions in a single run :) Of course it is not too fast
Mr. Xcoder
Now waiting to be outgolfed. I think it's possible in sub-35/30, but I don't think I'll be able to do anything much shorter
Mr. Xcoder
2

Jelly, 34 bytes

BṚT’2*
PÇŒṗæḟ2⁼ƊƇ€ŒpẎṢ⁼Ṣ}ʋƇÇ€×þ/ẎƊ

Try it online!

Input format: [P, Q] (the TIO link above doesn't accept this, but a single number instead, to aid with the test cases).

Output format: List of all solutions (shown as grid representation of 3D list over TIO).

Speed: Turtle.

Erik the Outgolfer
źródło
1

Haskell, 281 195 bytes

import Data.List
r=reverse.sort
n#0=[]
n#x=[id,(n:)]!!mod x 2$(n*2)#div x 2
m!0=[]
m!x=m!!0:tail m!(x-m!!0)
m%[]=[]
m%n=m!head n:drop(length$m!head n)m%tail n
p&q=r[x*y|x<-1#p,y<-1#q]%r(1#(p*q))
Евгений Новиков
źródło
1
Oto kilka wskazówek: Definiowanie operatorów zamiast funkcji binarnych jest tańsze, przestawianie osłon i dopasowywanie wzorców może cię zaoszczędzić (==), użyj 1>0zamiast Truei nie używaj where. Również n'można skrócić .. Dzięki temu można zaoszczędzić 72 bajtów: Spróbuj online!
ბიმო
Btw. you should check out the Haskell tips section if you havent.
ბიმო
I had a look at the guard situation again, another 13 bytes off: Try it online!
ბიმო
@OMᗺ, thank you. I'm new to haskell, so this looks for me as magic tricks
Евгений Новиков
No worries :) In case you have questions, feel free to ask in Of Monads and Men.
ბიმო