18
\$\begingroup\$

Now that we know how to properly square and triangle a number, we are going to learn how to parallelogram one. To parallelogram a number, we first arrange it as a parallelogram by stacking it on top of itself a number of times equal to the number of digits it has, and adding spaces to make it a parallelogram. So 123 would form:

   123
  123
 123

Now we take each horizontal and vertical number and add them, 123+123+123+1+12+123+23+3, which equals 531, which is the parallelogram of 123.

Your Task:

Write a program or function that, when given a number as input, returns the parallelogram of the number.

Input:

A non-negative integer, or a non-negative integer represented by a string.

Output:

The parallelogram of the integer.

Test Cases:

1234567 -> 10288049
123     -> 531
101     -> 417
12      -> 39

Scoring:

This is , lowest score in bytes wins!

\$\endgroup\$

21 Answers 21

9
\$\begingroup\$

MATL, 12 bytes

tnEXyPY+c!Us

Input is a string. Try it online!

Explanation

Consider input '123' as an example.

The code duplicates the input (t) and builds an identity matrix (Xy) of size twice the input length (nE):

1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1

then flips it upside down (P):

0 0 0 0 0 1
0 0 0 0 1 0
0 0 0 1 0 0
0 0 1 0 0 0
0 1 0 0 0 0
1 0 0 0 0 0

The input string, interpreted as ASCII codes of the digits, is equivalent to the numeric row vector

49 50 51

Full-size two-dimensional convolution (Y+) of the above vector and matrix gives

 0  0  0  0  0 49 50 51
 0  0  0  0 49 50 51  0
 0  0  0 49 50 51  0  0
 0  0 49 50 51  0  0  0
 0 49 50 51  0  0  0  0
49 50 51  0  0  0  0  0

Interpreting those numbers back as ASCII codes (c) gives the following char matrix, with char 0 represented as space:

     123
    123 
   123  
  123   
 123    
123

Transposition (!) transforms this into

     1
    12
   123
  123 
 123  
123   
23    
3     

Interpreting each row as a number (U) gives the numeric column vector

  1
 12
123
123
123
123
 23
  3

and summing it (s) gives the final result, 531.

\$\endgroup\$
  • 1
    \$\begingroup\$ I smell... convolution \$\endgroup\$ – Adnan Aug 8 '17 at 23:18
  • 1
    \$\begingroup\$ @Adnan What else? :-D \$\endgroup\$ – Luis Mendo Aug 8 '17 at 23:23
6
\$\begingroup\$

Retina, 22 bytes

.
$`;$&$';$_;
\d+
$*
1

Try it online! Link includes test cases. Explanation: The first stage splits the input number at each digit and includes all the exclusive prefixes and inclusive suffixes, giving the vertical numbers, plus also the original input number repeated for each digit, giving the horizontal numbers. The remaining stages then simply sum the resulting numbers.

\$\endgroup\$
6
\$\begingroup\$

05AB1E,  12 11  8 bytes

I'm sure knew this can could be golfed further - tips welcome!

-1 byte thanks to Erik the Outgolfer (avoid wraps but using a concatenation)
and then...
-3 more bytes thanks to Adnan (avoid multiplication by length-1 by vectorising addition and subtracting the input off at the end)

.s¹η++Oα

Try it online!

How?

.s¹η++Oα - implicit input, say i      e.g.  123
.s       - suffixes                         [3,23,123]
  ¹      - push i                           123
   η     - prefixes                         [1,12,123]
    +    - addition of top two              [4,35,246]
     +   - addition (vectorises)            [127,158,369]
      O  - sum                              654
       α - absolute difference abs(123-654) 531
         - implicit print
\$\endgroup\$
  • \$\begingroup\$ You can use « to concatenate the suffixes and the prefixes: g<*¹.s¹η«O+ \$\endgroup\$ – Erik the Outgolfer Aug 9 '17 at 9:48
  • 1
    \$\begingroup\$ .s¹η++Oα should work for 8 bytes \$\endgroup\$ – Adnan Aug 9 '17 at 10:02
  • \$\begingroup\$ Thanks @EriktheOutgolfer the two wraps did seem odd to me! \$\endgroup\$ – Jonathan Allan Aug 9 '17 at 10:15
  • \$\begingroup\$ @Adnan - that's pretty sweet! \$\endgroup\$ – Jonathan Allan Aug 9 '17 at 10:16
  • \$\begingroup\$ @JonathanAllan "tips welcome!" not sure if you'll get any anymore... \$\endgroup\$ – Erik the Outgolfer Aug 9 '17 at 10:16
5
\$\begingroup\$

Haskell, 90 78 76 71 64 63 59 57 bytes

g x=sum[x+div x(10^a)+mod x(10^a)|(a,_)<-zip[1..]$show x]

Try it online!

\$\endgroup\$
  • \$\begingroup\$ g x=sum[x+div x a+mod x a|(a,_)<-zip((10^)<$>[1..])$show x]. \$\endgroup\$ – nimi Aug 9 '17 at 20:08
  • \$\begingroup\$ g x=sum[x+div x(10^a)+mod x(10^a)|(a,_)<-zip[1..]$show x] is a hair shorter still. \$\endgroup\$ – Lynn Aug 9 '17 at 22:27
  • \$\begingroup\$ g x=sum[x+x`div`10^a+x`mod`10^a|(a,_)<-zip[1..]$show x]. \$\endgroup\$ – Laikoni Aug 10 '17 at 12:19
4
\$\begingroup\$

Husk, 13 12 bytes

ṁit§+SRL§+ḣṫ

Try it online!

Explanation

              -- implicit input, say "123"
   §+         -- concatenate the results of the following two functions
     SR       --  ¹repeat the input n times, where n is the result of the next function
       L      --   length                                                  ["123","123"]
        §+   --  ²concatenate the results of the following two functions
          ḣ  --     prefixes                                              ["","1","12","123"]
           ṫ --     suffixes                                              ["123","23","3",""]
              -- inner concatenation                                      ["","1","13","123","123","23","3",""]
              -- outer concatenation                                      ["123","123","","1","13","123","123","23","3",""]
  t           -- all but the first element                                ["123","","1","13","123","123","23","3",""]
ṁ             -- map then sum
 i            --   convert to integer (where "" converts to 0)
\$\endgroup\$
4
\$\begingroup\$

Neim, 7 bytes

𝐱S𝐗𝔻𝔻𝐬𝕤

Beware. Contains snakes: S𝐬𝕤

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ "Beware. Contains snakes: S𝐬𝕤" Lol.. 𝐗𝔻 \$\endgroup\$ – Kevin Cruijssen Aug 10 '17 at 8:06
4
\$\begingroup\$

Python 3, 85 70 Bytes

f=lambda n,r=1,i=int:n[r:]and i(n[r:])+i(n[:r])+f(n,r+1)+i(n)or i(n)*2

For input 12345:

Sums up slices of input 1+2345+12345, 12+345+12345, 123+45+12345, 1234+5+12345, by using string indexing to index (r) = 1,2,3,4 before casting to integer, and adds to 12345*2

Special Thanks to:

-14 Bytes @Jonathan Allen

-1 Byte @ovs

Try it online!

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

Japt, 15 11 bytes

-4 bytes thanks to @Shaggy.

¬£iYç
cUz)x

Takes input as strings.

Try it online!

Explanation

£

Split the input array to digits (¬) and map by (£) the following function, where Y is the index.
["1", "2", "3"]

iYç

The input value (implicit) with Y spaces (ç) inserted (i) at the beginning. This is assigned to U.
["123", " 123", " 123"]

cUz1)x

Concatenate that with itself rotated 90° right (1 time). Then sum (x).
["123", " 123", " 123", " 1", " 12", "123", "23 ", "1 "] -> 531.

\$\endgroup\$
  • \$\begingroup\$ Exactly how I was trying to do it, but I couldn't quite get there, for some reason - nicely done :) Here's a 13 byte version. \$\endgroup\$ – Shaggy Aug 9 '17 at 10:23
  • \$\begingroup\$ 11 bytes \$\endgroup\$ – Shaggy Aug 9 '17 at 10:29
  • \$\begingroup\$ @Shaggy Awesome, I knew there had to be a shorter way to prepend the spaces to each line. Thanks! \$\endgroup\$ – Justin Mariner Aug 9 '17 at 10:32
3
\$\begingroup\$

Japt, 31 18 bytes

-13 bytes thanks to @ETHproductions

This approach doesn't work well using Japt. Justin's solution is much better.

[U*Ål U¬£tYÃUå+]xx

Explanation:

[U*Ål U¬£tYÃUå+]xx
[              ]    // Create a new array
 U*Ål               // Push: Input * Input.slice(1).length()
                    // Push:
      U¬            //   Input, split into chars
        £tY         //   Map; At each char: .substr(Index)
            Uå+     // Push: Cumulative reduce Input; with addition
                xx  // Sum all the items, twice

Try it online!

\$\endgroup\$
  • 3
    \$\begingroup\$ That's it, I'm adding a shortcut for Ul  :P \$\endgroup\$ – ETHproductions Aug 9 '17 at 1:36
  • \$\begingroup\$ Hmm... you don't need either of the Us in the functions, and the middle item in the array can be condensed to Uå+ x, which I think gets you down to 23 bytes. \$\endgroup\$ – ETHproductions Aug 9 '17 at 1:53
  • \$\begingroup\$ @ETHproductions Thanks! I got it down another byte by rearranging the array items. \$\endgroup\$ – Oliver Aug 9 '17 at 2:03
  • \$\begingroup\$ Can you change mx x to xx? :-) \$\endgroup\$ – ETHproductions Aug 9 '17 at 2:07
  • \$\begingroup\$ @ETHproductions I sure can, thanks again :) \$\endgroup\$ – Oliver Aug 9 '17 at 2:12
2
\$\begingroup\$

Ruby, 61 55+1 = 56 bytes

Uses the -n flag. Input from STDIN.

p (1..~/$/).sum{|i|[$_[i,~/$/],$_[0,i],$_].sum &:to_i}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ For input 102033 your program prints 728714 while the correct value is 729702. \$\endgroup\$ – user72349 Aug 8 '17 at 22:58
  • \$\begingroup\$ NOOOO! CURSE YOU OCTAL REPRESENTATIONS! (brb fixing, 02033 was the issue) \$\endgroup\$ – Value Ink Aug 8 '17 at 23:06
  • \$\begingroup\$ I supposed that octal numbers are the problem, but I was not sure (btw I don't know ruby). Thanks for clarifying :) \$\endgroup\$ – user72349 Aug 8 '17 at 23:08
  • \$\begingroup\$ @ThePirateBay no problem; I was already working on a shorter, alternate solution that took string inputs, and even with the fixes needed I actually ended up saving bytes anyways :) \$\endgroup\$ – Value Ink Aug 8 '17 at 23:13
2
\$\begingroup\$

JavaScript, 77 74 bytes

Saved 3 bytes thanks to Value Ink

f=a=>[...a+a].map((_,b)=>a-=-z.substr((b-=n)>0?b:0,b+n),a*=n=(z=a).length)|a

console.log(f('123'));
console.log(f('101'));
console.log(f('12'));
console.log(f('1234567'));
console.log(f('102033'));

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

Pyth, 20 19 bytes

My current prefix approach (will hopefully golf further).

+*tlQsQssM+_M.__Q._

Test Suite or try an alternative approach with the same byte count.

Explanation

+*tlQsQssM+_M.__Q._  - Full program that reads a String from STDIN, with implicit input.

  tlQ                - Length of the input - 1.
     sQ              - The input converted to an integer.
 *                   - Product of the above two elements. We will call this P.
                 ._  - Prefixes of the input.
          +          - Concatenated with:
           _M.__Q    - The prefixes of the reversed input, reversed.
        sM           - Convert each to an integer.
       s             - Sum.
+                    - Addition of the product P and the sum above.

To understand the concept better, we shall take an example, say "123".

  • We first get the prefixes of the input. Those are ['1', '12', '123'].

  • Then, we get the prefixes of the reversed input, i.e: ['3', '32', '321'] and reverse each, hence we get ['3', '23', '123'].

  • We concatenate the two lists and convert each element to an integer, so we obtain [3, 23, 123, 1, 12, 123].

  • By summing the list, the result is 285.

  • The product P is the length of the input - 1 (i.e 2) multiplied by the integer representation of it (2 * 123 = 246).

  • In the end, we sum the two results: 285 + 246, hence we obtain 531, which is the correct result.


Pyth, 20 bytes

+*hlQsQsm+s>Qds<QdtU

Test Suite.

Explanation

Explanation to come after further golfing. I didn't succeed to golf this further for now (I have ideas though).

+*hlQsQsm+s>Qds<QdtUQ  - Full program. Reads from STDIN. Q means input, and is implicit at the end.

  hlQ                  - Length of the input + 1.
     sQ                - The input converted to an integer.
 *                     - Multiply the above. We'll call the result P.
        m         tUQ  - Map over [1...length of the input)
          s>Qd         - input[currentItem:] casted to an integer.
              s<Qd     - input[:currentItem] casted to an integer.
         +             - Sum the above.
       s               - Sum the list.
+                      - Add the sum of the list and P.
\$\endgroup\$
1
\$\begingroup\$

q/kdb+, 34 bytes

Solution:

{sum"J"$((c#c),c-(!)2*c:(#)x)#\:x}

Examples:

q){sum"J"$((c#c),c-(!)2*c:(#)x)#\:x}"1234567"
10288049
q){sum"J"$((c#c),c-(!)2*c:(#)x)#\:x}"123"    
531
q){sum"J"$((c#c),c-(!)2*c:(#)x)#\:x}"101"    
417
q){sum"J"$((c#c),c-(!)2*c:(#)x)#\:x}"12"     
39

Explanation:

{sum"J"$((c#c),c-til 2*c:count x)#\:x} / ungolfed
{                                    } / lambda function
                                    x  / implicit input
                                 #\:   / apply take (#) to each-left element with the right element
        (                       )      / the left element
                       c:count x       / count length and save in variable c
                     2*                / multiply by 2 (e.g. 6)
                 til                   / range, so 0 1 2 3 4 5
               c-                      / vector subtraction, so 3 2 1 0 -1 -2
         (   )                         / do this together
          c#c                          / 3 take 3, so 3 3 3
              ,                        / join, so 3 3 3 3 2 1 0 - 1 -2          
    "J"$                               / cast this "123", "123", "123" .. "23" to longs
 sum                                   / sum them up and return result
\$\endgroup\$
1
\$\begingroup\$

Jelly, 18 bytes

DµṚ;\U;;\ṖVS+Ḍ×¥L$

Try it online!

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

Swift 3, 213 bytes

func f(n:String){print((n.characters.count-1)*Int(n)!+(0..<n.characters.count).map{r in Int(n[n.index(n.startIndex,offsetBy:r)..<n.endIndex])!+Int(n[n.startIndex..<n.index(n.endIndex,offsetBy:-r)])!}.reduce(0,+))}

Cannot be tested online, because it is slow and times out. You can try it in Swift Playgrounds if you wish to test it.

Sample run

Input:

f(n:"123")
f(n:"101")
f(n:"1234567")

Output:

531
417
10288049
\$\endgroup\$
1
\$\begingroup\$

Jelly, 12 bytes

LḶṚ⁶ẋ;€µ;ZVS

Try it online!

Takes input as a string. Creates the "parallelogram" as a matrix of characters, then evaluates each row and column to get the numbers to sum.

Explanation

LḶṚ⁶ẋ;€µ;ZVS  Input: string S
L             Length
 Ḷ            Lowered range - [0, 1, ..., len(S)-1]
  Ṛ           Reverse
   ⁶          The char ' ' (space)
    ẋ         Create that many characters of each in the range
     ;€       Prepend each to S
       µ      Begin a new monadic chain
        ;     Concatenate with
         Z    Transpose
          V   Eval each string
           S  Sum
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 95 84 81 bytes (78 + -lm compiler flag)

Hi! This is my first submission, I hope I didn't break any rule.

g,o,l;f(char*s){l=atoi(s);while(s[o++])g+=l/pow(10,o)+atoi(s+o);return g+l*o;}

Try it online!

Ungolfed, without warnings:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int g,o,l;

int f(char *s){
  l = atoi(s);

  while(s[o++]) {
    g+=l/pow(10,o)+atoi(s+o);
  }

  return g+l*o;
}

int main(void){
  printf("%d\n",f("1234567"));
  return 0;
}
\$\endgroup\$
  • \$\begingroup\$ Looks valid to me :) \$\endgroup\$ – Okx Aug 9 '17 at 10:49
  • \$\begingroup\$ Hmm, -lm for math functions is only needed for some C runtimes like e.g. glibc. Compiling e.g. with MinGW (using Microsoft's msvcrt.dll), it wouldn't be needed. So not sure it's required to add here? Anyways, if you add it, it would make 3 bytes ;) \$\endgroup\$ – Felix Palmen Aug 9 '17 at 12:56
  • \$\begingroup\$ Unfortunately, -lm is needed for the pow() function with gcc. I tried to work without it but couldn't find a solution using fewer than 6 bytes (pow + the compiler flag). I couldn't find rules about how to include flags into the bytecount, and I know realize that I made a false assumption about the - character not beeing counted. I'm adding a +1 byte right now. \$\endgroup\$ – scottinet Aug 9 '17 at 13:23
  • \$\begingroup\$ -lm is not required by gcc but by the fact that glibc doesn't include the math functions in the main library. msvcrt.dll does, so compiling on windows with gcc works without the -lm. This is nitpicking and I'm not entirely sure what the rules about this actually have to say. \$\endgroup\$ – Felix Palmen Aug 9 '17 at 13:28
  • \$\begingroup\$ Thanks for the heads up :) I'm unable to try your proposal and tio doesn't seem to offer that possibility either, unfortunately \$\endgroup\$ – scottinet Aug 9 '17 at 13:34
1
\$\begingroup\$

Java 8, 147 137 126 116 114 bytes

n->{Integer l=(n+"").length(),r=n*l,i=0;for(;++i<l*2;)r+=l.valueOf((n+"").substring(i>l?i-l:0,i<l?i:l));return r;}

-13 bytes (137 → 126 and 116 → 114) thanks to @OlivierGrégoire.

Explanation:

Try it here.

n->{                          // Method with integer as parameter and return-type
  Integer l=(n+"").length(),  //  Length of the input integer
      r=n*l,                  //  Result-integer (starting at `n*l`)
      i=0;                    //  Index-integer (starting at 0)
  for(;++i<l*2;               //  Loop from 0 through two times `l` (exclusive)
    r+=                       //   Add to the result-integer sum:
       l.valueOf((n+"").substring(
                              //    Substring of input, converted to integer:
        i>l?                  //     If `i` is larger than `l`:
         i-l                  //      Substring starting at `i-l`
        :                     //     Else:
         0,                   //      Substring starting at 0
        i<l?                  //     If `i` is smaller than `l`:
         i                    //      Substring ending at `i` (exclusive)
        :                     //     Else:
         l)                   //      Substring ending at `l` (exclusive)
  );                          //  End of loop
  return r;                   //  Return resulting sum
}                             // End of method
\$\endgroup\$
  • 1
    \$\begingroup\$ 114 bytes: n->{Integer l=(n+"").length(),s=n*l,i=0;for(;++i<l*2;)s+=l.valueOf((n+"").substring(l<i?i-l:0,i<l?i:l));return s;}. It's a sliding window with min-max to reduce the number of calls to the expensive new Integer(....substring(...)) \$\endgroup\$ – Olivier Grégoire Aug 10 '17 at 12:44
  • 1
    \$\begingroup\$ @OlivierGrégoire Thanks, and can even shortened some more by changing Math.max(0,i-l) to 0>i-l?0:i-l and Math.min(i,l) to i>l?l:i. Modifying it now. Ah, I see you've edited your comment after I had copied the 126 bytes answer. ;) \$\endgroup\$ – Kevin Cruijssen Aug 10 '17 at 12:51
  • \$\begingroup\$ Yeah, sorry for editing, but I hadn't checked that ;) \$\endgroup\$ – Olivier Grégoire Aug 10 '17 at 12:53
1
\$\begingroup\$

R, 168 162 103 bytes

-6 bytes by not using c()

-59 bytes thanks to @Giuseppe

function(n){k=nchar(n)
a=k*strtoi(n)
for(i in 1:k)for(j in i:k)a=a+(i==1|j==k)*strtoi(substr(n,i,j))
a}

Try it online!

Takes input as a string.

I'm absolutely certain there are improvements to be made, primarily in leveraging any of R's strengths... but in a challenge that's basically string manip, I'm struggling to see how.

Edit: Much better now that I'm not iterating on a bad idea!

\$\endgroup\$
  • 1
    \$\begingroup\$ 103 bytes \$\endgroup\$ – Giuseppe Aug 10 '17 at 15:36
  • \$\begingroup\$ @Giuseppe Ah thanks! That was a lot of wasted space from when I was still using an integer input. I like the strtoi(substr()) way, and the (a|b) trick is way smarter than I had. Thanks for the improvements! It's almost a different answer at this point... \$\endgroup\$ – CriminallyVulgar Aug 10 '17 at 15:53
  • \$\begingroup\$ That happens when you get another approach added! I couldn't figure out the loops myself, but I think you might be able to construct the indices for substr explicitly instead of looping, which would save a few bytes. \$\endgroup\$ – Giuseppe Aug 10 '17 at 16:06
0
\$\begingroup\$

Perl 5, 53 + 1 (-n) = 54 bytes

$r=$_*(@n=/./g);for$i(@n){$r+=$_+($t=(chop).$t)}say$r

Try it online!

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

Mathematica, 77 bytes

(s=IntegerDigits@#;t=Length@s;Tr[FromDigits/@Table[s~Take~i,{i,-t,t}]]+t#-#)&
\$\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.