39
\$\begingroup\$

Inspired by this question from our rivals friends over at Code Review.

Definitions

A super array is an array where each new element in the array is larger than the sum of all the previous elements. {2, 3, 6, 13} is a super array because

3 > 2
6 > 3 + 2 (5)
13 > 6 + 3 + 2 (11)

{2, 3, 5, 11} is not a super array, because

3 > 2
5 == 3 + 2
11 > 5 + 3 + 2

A duper array is an array where each new element in the array is larger than the product of all the previous elements. {2, 3, 7, 43, 1856} is a super array, but it is also a duper array since

3 > 2
7 > 3 * 2 (6)
43 > 7 * 3 * 2 (42)
1856 > 43 * 7 * 3 * 2 (1806)

The challenge

Write a function or program that takes an array as input in your languages native list format, and determines how super the array is. You can also optionally take an array length input (for languages like C/C++). Also, you can assume that all of the numbers in the list will be integers greater than 0. If it's a super array, you must print It's a super array! If it is a super duper array, you must print It's a super duper array! It's also possible for an array to be duper-non-super. For example {1, 2, 3} In this case, you should print It's a duper array! If the array is neither super nor duper, you can print a falsy value.

As usual, this is code golf, so standard loopholes apply, and the shortest answer in bytes wins.

\$\endgroup\$
  • 9
    \$\begingroup\$ I don't like the cumbersome I/O format, but it may be too late to change now. \$\endgroup\$ – lirtosiast Jan 19 '16 at 2:27
  • 1
    \$\begingroup\$ I'm sure you meant "duper-non-super" for the {1, 2, 3} array? \$\endgroup\$ – Darrel Hoffman Jan 19 '16 at 15:43
  • 1
    \$\begingroup\$ @DJMcMayhem oops, I somehow got 2 * 1 to equal 3 in my head. \$\endgroup\$ – Alexander Revo Jan 19 '16 at 20:39
  • 4
    \$\begingroup\$ This came up in a comment: Your spec says If the array is neither super nor duper, you can print a falsy value. Does this mean we must print a falsy value? \$\endgroup\$ – Dennis Jan 20 '16 at 14:55
  • 1
    \$\begingroup\$ Would it matter is there's 2 spaces between a word somewhere? I could still save more if super[space][space]array is allowed. \$\endgroup\$ – aross Jan 22 '16 at 11:20

15 Answers 15

20
\$\begingroup\$

Jelly, 47 45 4̷4̷ 42 bytes

+\,×\<ḊZṖP“sd”x;€“uper ”;/“It's a ”,“¥ṫɲ»j

This prints an empty string (falsy) for arrays that are neither super nor duper. Try it online!

How it works

+\,×\<ḊZṖP“sd”x;€“uper ”  Main link (first half). Argument: A (array)

+\                        Compute all partial sums of A.

   ×\                     Compute all partial products of A.
  ,                       Pair the results to the left and to the right.
     <Ḋ                   Perform vectorized comparison with A[1:].
                          This yields a 2D array of Booleans.
       Z                  Zip; pair the Booleans corresponding to each integer.
        Ṗ                 Remove the last pair.
                          (Nothing is compared with the last sum/product.)
         P                Take the product of each column.
          “sd”x           Perform vectorized character repetition.
                          This yields ['s', d'], ['s'], ['d'], or [].
               ;€“uper ”  Append the string "uper " to each character.


;/“It's a ”,“¥ṫɲ»j        Main link (second half).

;/                        Reduce the resulting array of strings by concatenation.
                          This will fail for an empty array, exiting immediately.
  “It's a ”,“¥ṫɲ»         Push ['It's a ', 'array!'].
                 j        Join that array, separating by the super duper string.
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice way as usual, Dennis :) Been gone for a while, time to read the Jelly docs ;) \$\endgroup\$ – Kade Jan 19 '16 at 4:28
  • \$\begingroup\$ Is there any documentation how string compression works in Jelly? \$\endgroup\$ – Luis Mendo Jan 19 '16 at 12:27
  • \$\begingroup\$ @LuisMendo Not right now. There current compression method is experimental and I'll change it soon. A quick overview: Using the indices in the code page, the compressed string is converted from bijective base 250 to integer. Each step either decodes to a printable ASCII character or a word of the dictionary, possible with changed case and/or a space before it. \$\endgroup\$ – Dennis Jan 19 '16 at 13:56
9
\$\begingroup\$

JavaScript (ES6), 111 110 bytes

Saved a byte thanks to @ETHproductions!

a=>a.map((n,i)=>i&&(s=s&&n>s&&s+n,d*=d&&n>d&&n),s=d=a[0])|s|d&&`It's a ${s?"super ":""}${d?"duper ":""}array!`

Explanation

Takes an array of numbers, returns a string or the number 0 for false.

a=>
  a.map((n,i)=>      // for each number n at index i
    i&&(             // skip the first number (because s and d are initialised to it)
      s=s&&n>s&&s+n, // if it is still super and n > s, s += n, else s = false
      d*=d&&n>d&&n   // if it is still duper and n > d, d *= n, else d = false
    ),
    s=               // s = sum of previous numbers if super, else false
    d=               // d = product of previous numbers if duper, else false
      a[0]           // initialise s and d to the first number
  )
  |s|d               // if it is neither super or duper, output 0

  // Output the appropriate string
  &&`It's a ${s?"super ":""}${d?"duper ":""}array!`

Test

var solution = a=>a.map((n,i)=>i&&(s=s&&n>s&&s+n,d*=d&&n>d&&n),s=d=a[0])|s|d&&`It's a ${s?"super ":""}${d?"duper ":""}array!`
Numbers (space-separated) = <input type="text" id="input" value="2 3 7 43 1856" />
<button onclick="result.textContent=solution(input.value.split(' ').map(n=>+n))">Go</button>
<pre id="result"></pre>

\$\endgroup\$
  • \$\begingroup\$ That's a clever way to do this! I think you can save two bytes with s+=s&&n>s&&n,d*=d&&n>d&&n \$\endgroup\$ – ETHproductions Jan 19 '16 at 2:32
  • \$\begingroup\$ @ETHproductions s needs to be done this way because it needs to be set to false if n>s, but d*false has the same effect so that one works. Thanks! \$\endgroup\$ – user81655 Jan 19 '16 at 2:41
5
\$\begingroup\$

Java, 183 182 Bytes

String w(int[]a){boolean s=1<2,d=s;int m=a[0],p=m,k=a.length,i=0,e;if(k>0)for(;++i<k;s&=e>m,d&=e>p,m+=e,p*=e)e=a[i];return d|s?"It's a "+(s?"super ":"")+(d?"duper ":"")+"array!":"";}

I made the following assumptions:

  • The output is via return value.
  • The empty String "" is a falsy value.

If any of these are wrong, please tell me.

Anyway, I can't shake the feeling that I might have gone overboard with the amount of variables.

Edit: managed to save a byte, thanks to @UndefinedFunction

\$\endgroup\$
  • 1
    \$\begingroup\$ Would it be possible to change boolean s=true to boolean s=1<2 ? \$\endgroup\$ – jrich Jan 21 '16 at 1:57
  • \$\begingroup\$ @UndefinedFunction Yes, good catch \$\endgroup\$ – ECS Jan 21 '16 at 8:08
4
\$\begingroup\$

MATL, 66 bytes

Ys5L)G6L)XK<?' super']GYp5L)K<?' duper']N?N$h'It''s a'wh' array!'h

Uses current release (10.0.3), which is earlier than this challenge.

Input is from stdin. If not super or duper, output is empty (which is falsey).

EDIT (April 7, 2016): due to changes in release 16.0.0 of the language, 5L and 6L need to be replaced by 3L and 4L repectively. The link to the online compiler includes those modifications.

Try it online!

Explanation

Ys             % implicit input. Cumulative sum
5L)            % remove last element
G6L)           % push input. Remove first element
XK             % copy to clipboard K
<?             % if all elements are smaller
  ' super'     % push string
]              % end
GYp            % push input. Cumulative product
5L)            % remove last element
K              % push input except first element
<?             % if all elements are smaller
  ' duper'     % push string
]              % end
N?             % if stack not empty
  N$h          % concatenate all elements (will be one or two strings)
  'It''s a'    % string
  wh           % prepend
  ' array!'    % string
  h            % concatenate. Implicit end. Implicit display
\$\endgroup\$
3
\$\begingroup\$

C++14, 178, ..., 161 157 bytes

Can't think of a way to make it any shorter. Seems like there's always some room for improvement!

Update 1: I'm all for safe code, but taking a raw array and its size as function arguments is 9 bytes shorter than taking a vector :(

Update 2: Now returns an empty string as false-value, at cost of 8 bytes.

Update 3: Back to 165 bytes, thanks to CompuChip's comment.

Update 4: Another comment by CompuChip, another 4 bytes off.

Update 5: using auto instead of string along with another suggestion by CompuChip shaves another 4 bytes off the code.

auto f(int*a,int n){int s,p,d=1,e=1,r;for(s=p=*a;--n;s+=r,p*=r)r=*++a,e=r>s?e:0,d=r>p?d:0;return e|d?"It's a "s+(e?"super ":"")+(d?"duper ":"")+"array!":"";}

Ungolfed full program with test cases:

#include <iostream>
#include <string>
#include <vector>

using namespace std::literals::string_literals;

auto f(int* a, int n)
{
    int s,p,d=1,e=1,r;

    for(s=p=*a; --n; s+=r, p*=r)
        r=*++a, e=r>s?e:0, d=r>p?d:0;

    return e|d ? "It's a "s + (e?"super ":"") + (d?"duper ":"") + "array!" : "";
}

int main()
{
    std::vector<std::vector<int>> test_cases = {{2,3,6,13},
                                                {2,3,5,11},
                                                {2,3,7,43,1856},
                                                {1,2,3}
                                               };

    for(auto& test_case : test_cases)
    {
        std::cout << f(test_case.data(), test_case.size()) << '\n';
    }
}

Output:

It's a super array!

It's a super duper array!
It's a duper array!
\$\endgroup\$
  • 2
    \$\begingroup\$ The string It's a array! is truthy (proof) according to our definition on Meta. \$\endgroup\$ – Dennis Jan 19 '16 at 23:43
  • \$\begingroup\$ @Dennis actually, it's a compile error (I'm using a C++14 std::string literal, not raw character array), which is neither. Anyway, I'm updating my answer to print an empty string now, as that is the approach used in other solutions. \$\endgroup\$ – Alexander Revo Jan 20 '16 at 7:04
  • 1
    \$\begingroup\$ You can shave of a few more bytes if you lose the length if ... >= comparisons: I think e=r>s?e:0 is equivalent to if(r<=s)e=0. \$\endgroup\$ – CompuChip Jan 20 '16 at 9:08
  • 1
    \$\begingroup\$ @AlexanderRevo doesn't something like for(s=p=*a;--n;s+=r,p*=r)r=*++a work? Would allow you to drop i altogether \$\endgroup\$ – CompuChip Jan 20 '16 at 13:26
  • 1
    \$\begingroup\$ Can't you avoid one of the increments? The one in the initializer seems unnecessary? Or does that give you one loop iteration too many? \$\endgroup\$ – CompuChip Jan 20 '16 at 14:06
2
\$\begingroup\$

C, 150 bytes

#define M(N,O)N(int*d,int c){return*d?*d>c?N(d+1,c O*d):0:1;}
M(S,+)M(D,*)Z(int*d){printf("It's a %s%s array!\n",S(d,0)?"super":"",D(d,0)?"duper":"");}

Each input is terminated by a 0. Test main:

#include <stdio.h>

int main() {
  int test_data[4][6] = {
    {2, 3, 7, 43, 1856, 0}, // superduper
    {2, 3, 5, 11, 0}, // not super
    {2, 3, 6, 13, 0}, // super
    {1, 2, 3, 0} // duper not super
  };

  for (int i = 0; i < 4; ++i) {
    Z(test_data[i]);
  }
}

Bonus if we are allowed a more compact output format, we can cut it to 107 bytes:

#define M(N,O)N(int*d,int c){return*d?*d>c?N(d+1,c O*d):0:1;}
M(S,+)M(D,*)Z(int*d){return S(d,0)*2^D(d,0);}

In this case, Z return 3 for superduper, 2 for super, 1 for duper and 0 for none.

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

Pyth - 54 52 bytes

The string formatting part can probably be golfed, but I like the super-duper testing approach.

jd++"It's a"fT*V+R"uper""sd"m*F>VtQd,sMK._Q*MK"array

Test Suite.

\$\endgroup\$
  • 1
    \$\begingroup\$ c2"superduper" can be golfed to +R"uper""sd" \$\endgroup\$ – isaacg Jan 19 '16 at 1:28
  • \$\begingroup\$ @isaacg that's really smart \$\endgroup\$ – Maltysen Jan 19 '16 at 1:29
  • 3
    \$\begingroup\$ You're missing the exclamation mark, I think \$\endgroup\$ – ETHproductions Jan 19 '16 at 1:47
  • 4
    \$\begingroup\$ @TrangOul lang-pyth doesn't exist. \$\endgroup\$ – Dennis Jan 19 '16 at 14:54
  • 2
    \$\begingroup\$ This actually prints "It's a array" for non-super-non-duper arrays, which is a truthy string according to the definition on meta. Also, printed string should end with an exclamation mark. \$\endgroup\$ – Alexander Revo Jan 20 '16 at 7:20
1
\$\begingroup\$

Python 3, 127

Saved 5 bytes thanks to FryAmTheEggman.

Fairly basic solution right now, nothing too fancy. Just running a running total of sum and product and check each element.

def f(a):
 s=p=a[0];e=d=1
 for x in a[1:]:e&=x>s;d&=x>p;s+=x;p*=x
 return"It's a %s array!"%('super'*e+' '*e*d+'duper'*d)*(e|d)

Here's the test cases in case anyone else wants to try to beat my score.

assert f([2, 3, 6, 13]) == "It's a super array!"
assert f([2, 3, 5, 11]) == ''
assert f([2, 3, 7, 43, 1856]) == "It's a super duper array!"
assert f([1, 2, 3]) == "It's a duper array!"
print('All passed')
\$\endgroup\$
1
\$\begingroup\$

AWK - 140 bytes

awk 'BEGIN{d[1]=" super";e[1]=" duper";RS=" ";p=1;a=1;b=1}{a=a&&$1>s;b=b&&$1>p;s+=$1;p*=$1}END{printf "It'\''s a%s%s array!\n",d[a],e[b]}'

For those that don't know AWK, records are automatically parsed into lines based on variable RS and lines are automatically parsed into fields based on variable FS. Also unassigned variables are "" which when added to a # acts like a 0. The BEGIN section is called exactly once, before any records/fields are parsed. The rest of the language is fairly C-like with each matching code block being applied to each record. See http://www.gnu.org/software/gawk/manual/gawk.html#Getting-Started for more details.

Example run where 'code' is as above: echo 1 2 6 | 'code'

Could also place array in a file named Filename and run as: 'code' Filename

If the code is to run often it can be placed in an executable script file. This would remove the enclosing ' ' and the awk command would be placed at the top of the file as: #!/bin/awk -f

\$\endgroup\$
  • \$\begingroup\$ I don't know AWK, could anyone explain why this was downvoted? \$\endgroup\$ – Alexander Revo Jan 19 '16 at 21:57
  • \$\begingroup\$ Wasn't me, but I'd like an explanation of the code. Idk AWK either. \$\endgroup\$ – mbomb007 Jan 19 '16 at 22:40
  • \$\begingroup\$ This prints It's a array! for arrays that are neither super nor duper, which is a truthy string according to our definition on Meta. \$\endgroup\$ – Dennis Jan 19 '16 at 23:40
  • \$\begingroup\$ To test try: echo 1 2 6 | <the above code> \$\endgroup\$ – Robert Benson Jan 20 '16 at 13:08
  • 2
    \$\begingroup\$ @Dennis it's not like I'm nitpicking, but the challenge says "If the array is neither super nor duper, you can print a falsy value.", while in the other cases must is used instead. I'd say, as long as the output is clearly distinguishable from the other cases and correct, it should be fine. I'd like the word of OP on this. \$\endgroup\$ – Stefano Sanfilippo Jan 20 '16 at 14:51
1
\$\begingroup\$

PHP, 144 ... 113 112 Bytes

$x=super;$d=duper;foreach($a as$v){$v>$s||$x="";$v>$p||$d="";$s+=$v;$p=$p*$v?:$v;}echo$x.$d?"It.s a $x $d $a!":0;

Explanation:

// Initiate `$s` to prevent isset calls. Leaving this out yields PHP
// notices, but doesn't functionally change the code.
$s = 0;

// Set product to 1, so when multiplying with the first value, `$p` will
// equal `$v`.
$p = 1;

// Not existing constants `super` and `duper` yield PHP notices
// but are interpreted as strings.
$x = super;
$d = duper;

// Iterate over input (register_globals).
foreach ($a as $v) {
    // Check if current value "breaks" [sd]uper-ness: `value` not greater
    // than current sum or product. If so, unset the string.
    $v > $s || $x = "";
    $v > $p || $d = "";

    // Update sum.
    $s += $v;
    // Update product.
    $p *= $v;
}

// Check if super or duper strings are set, if so, wrap output in the
// appropriate string. Otherwise, output falsy value `0`.
echo $x . $d ? "It's a $x $d $a!" : 0;

Without register globals it would be this (118 bytes):

php -r '$x=super;$d=duper;for($p=1;$v=$argv[++$i];$p*=$v){$v>$s||$x="";$v>$p||$d="";$s+=$v;}echo$x.$d?"It.s a $x $d array!":0;' 2 3 7 43 1856 2>/dev/null;echo
  • Saved another 3 bytes by not caring about an extra space in the output
  • Saved 3 bytes by printing $a (array to string conversion yields Array)
  • Saved a byte by initializing $p to 1, so upping the product costs less.
\$\endgroup\$
  • \$\begingroup\$ Nice solution. A few notes: This is neither a full program nor a function as you don't handle your input $a. You don't have to worry about notices and stuff – simply ignore them on this site. \$\endgroup\$ – insertusernamehere Jan 21 '16 at 10:46
  • \$\begingroup\$ Should I replace it with $argv[1] instead? Is there a post in meta about acceptable input for PHP (or in general)? This is my first golf \$\endgroup\$ – aross Jan 21 '16 at 11:55
  • 2
    \$\begingroup\$ @aross Here you go. There's also this specifically about PHP but it never received a lot of attention. In general, STDIN and command-line arguments are fair game. You can also submit your code as a function. \$\endgroup\$ – Martin Ender Jan 21 '16 at 12:36
  • \$\begingroup\$ I think going with $argv[1] is a good alternative. That being said, this challenge is very vague about it's in- and output formats. But you might be penalized on other challenges with this approach. And hard coding the input is actually not acceptable – though there are some exceptions allowing it. I know that reading input is very expensive in PHP that's why I asked a similar question on meta about it. \$\endgroup\$ – insertusernamehere Jan 21 '16 at 12:36
  • \$\begingroup\$ My script would work with register_globals, but I'll write future golfs as a function instead. Why oh why was short_closures rejected? \$\endgroup\$ – aross Jan 21 '16 at 13:18
1
\$\begingroup\$

R, 115 bytes

function(x)cat("It's a",c("super","duper")[sapply(c(cumsum,cumprod),function(f)all(rev(x[-1]>f(x))[-1]))],"array!")

Try it online!

Falsy value: It's a array! Nothing too fancy here except maybe using sapply on a list of functions.

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

Scala, 172 Bytes

def f(a:Seq[Int])={var q=" super"
var w=" duper"
val x=a.head
a.drop(1).foldLeft((x,x)){case ((s,p),a)=>{if(s>=a)q=""
if(p>=a)w=""
(a+s,a*p)}}
println(s"It's a $q$w array")}

Ungolfed (although there really isn't much work to do so):

def f(input:Seq[Int])={
    var super=" super"
    var duper=" duper"
    val head=input.head
    input.drop(1).foldLeft((head,head)){
        case ((sum,product),val)=>
        {
            if(sum>=val)super=""
            if(product>=val)duper=""
                (val+sum,val*product)
        }
    }
    println(s"It's a $super$duper array")
}
\$\endgroup\$
0
\$\begingroup\$

Haskell, 136 Bytes

s o t=snd.foldl(\(s,b)x->(o s x,b&&x>s))(t,1>0)
f x="It's a "++(if s(+)0x then"super "else"")++(if s(*)1x then"duper "else"")++"array!"

f is the required function. Note that the empty sum is 0 and the empty product is 1 which is why [0] is neither super nor duper.

s captures the common structure of testing super or duper by taking an arbitrary operator o and an arbitrary neutral element t. The foldr keeps track of tuples (s,b) where s is the result of chaining all seen elements with the operator o and b says whether, for every element looked at so far, this element was larger than the previously computed sum/product.

The output is not golfed very much and I would appreciate it if someone contributed a better idea!

Slightly more readable version:

s :: (Integer -> Integer -> Integer) -> Integer -> [Integer] -> Bool
s o t = snd . (foldl (\(s,b) x -> (s `o` x, b && x>s)) (t, True))

f :: [Integer] -> [Char]
f x = "It's a " ++ (if s (+) 0 x then "super " else "")
      ++ (if s (*) 1 x then "duper " else "") ++ "array!"
\$\endgroup\$
0
\$\begingroup\$

05AB1E, 53 51 bytes

"It's"'a„dsIη©εRćsO›}Pè.•dwā•UX¦«®εRćsP›}PiX}„¦È!ðý

Try it online or verify all test cases.

Explanation:

"It's"             # Push string "It's"
'a                 # Push string "a"
„ds                # Push string "ds"
   Iη              # Get the prefixes of the input-list
     ©             # Store it in the register (without popping)
      ε     }      # Map each sub-list to:
       R           #  Reverse the list
        ć          #  Take the head extracted
         sO        #  Swap and take the sum
           ›       #  Check if the head is larger than the sum of the rest
             P     # Then check this is truthy for all sub-lists, resulting in 0 or 1
              è    # And use this to index into the "ds" string
.•dwā•             # Push string "duper"
      U            # Store it in variable `X` (with popping unfortunately)
       X¦          # Push `X` and remove the first character
         «         # Then merge it with the "d" or "s"
®εRćsP›}P          # Do the same as explained above, but with the product instead of sum
         i }       # If this resulted in 1:
          X        #  Push variable `X` ("duper")
„¦È!               # Push string "array!"
ðý                 # Join all strings on the stack by spaces (and output implicitly)

See here for an explanation of how .•dwā• is "duper" and how „¦È! is "array!".

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

Jelly, 37 bytes

Ä,×\<ḊZṖPµ“¤ḋГ¡e⁽»x'“¡Ƈɠİ[lɦ“Ñŀṙ»jẋẸ

Try it online!

Full program.

I got the Z…P idea from Dennis's (old) answer.

\$\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.