Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question
8  
I don't like the cumbersome I/O format, but it may be too late to change now. – lirtosiast Jan 19 at 2:27
1  
I'm sure you meant "duper-non-super" for the {1, 2, 3} array? – Darrel Hoffman Jan 19 at 15:43
    
@DarrelHoffman facepalm yup, editing now. – Dr Green Eggs and Iron Man Jan 19 at 15:46
1  
@DJMcMayhem oops, I somehow got 2 * 1 to equal 3 in my head. – Alexander Revo Jan 19 at 20:39
3  
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? – Dennis Jan 20 at 14:55

13 Answers 13

up vote 17 down vote accepted

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.
share|improve this answer
1  
Nice way as usual, Dennis :) Been gone for a while, time to read the Jelly docs ;) – Shebang Jan 19 at 4:28
    
Is there any documentation how string compression works in Jelly? – Luis Mendo Jan 19 at 12:27
    
@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. – Dennis Jan 19 at 13:56

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>

share|improve this answer
    
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 – ETHproductions Jan 19 at 2:32
    
@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! – user81655 Jan 19 at 2:41

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

share|improve this answer
1  
Would it be possible to change boolean s=true to boolean s=1<2 ? – jrich Jan 21 at 1:57
    
@UndefinedFunction Yes, good catch – ECS Jan 21 at 8:08

PHP, 211 205 174 Bytes

($a as $v){$x=!isset($x)?:$v>$s;$d=!isset($d)?:$v>$m;$s=isset($s)?$s+$v:$v;$m=isset($m)?$m*$v:$v;}$r=$x?"super ":false;$r.=$d?"duper ":false;echo$r?"It's a {$r}array!":false;

Readable:

foreach ($a as $v) {
    $x = !isset($super) ?: $v > $s;
    $d = !isset($d) ?: $v > $m;
    $s = isset($s) ? $s+$v : $v;
    $m = isset($m) ? $m*$v : $v;
}
$r = $x ? "super " : false;
$r .= $d ? "duper " : false;
echo $r ? "It's a {$r}array!" : false;

So far, i only can reduce to this.

Update1: changed the ternary operator logic.

Update2: Shorter variable names

share|improve this answer
    
This answer only determines "super-ness" and "duper-ness" for the first iteration, due to the isset call. It's therefore wrong. It also yields PHP notices. – aross Jan 21 at 9:00
    
A few notes:This is neither a full program nor a function as you don't handle your input $a. Your golfed code is missing foreach in the beginning. And you can save a few bytes: as$v and return '' or 0 instead of false. – insertusernamehere Jan 21 at 10:43

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
share|improve this answer

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!
share|improve this answer
2  
The string It's a array! is truthy (proof) according to our definition on Meta. – Dennis Jan 19 at 23:43
    
@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. – Alexander Revo Jan 20 at 7:04
1  
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. – CompuChip Jan 20 at 9:08
1  
@AlexanderRevo doesn't something like for(s=p=*a;--n;s+=r,p*=r)r=*++a work? Would allow you to drop i altogether – CompuChip Jan 20 at 13:26
1  
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? – CompuChip Jan 20 at 14:06

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.

share|improve this answer
1  
c2"superduper" can be golfed to +R"uper""sd" – isaacg Jan 19 at 1:28
    
@isaacg that's really smart – Maltysen Jan 19 at 1:29
3  
You're missing the exclamation mark, I think – ETHproductions Jan 19 at 1:47
4  
@TrangOul lang-pyth doesn't exist. – Dennis Jan 19 at 14:54
2  
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. – Alexander Revo Jan 20 at 7:20

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.

share|improve this answer

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')
share|improve this answer

PHP, 144 130 127 122 121 120 119 116 113 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 variables to prevent isset calls. Leaving this out yields PHP
// notices, but doesn't functionally change the code.
$s = $p = 0;

// 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, set to `$v` if 0 (only happens the first time).
    $p = $p * $v ?: $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 probably be an anonymous function (131 bytes):

function(&$z){$x=super;$d=duper;foreach($z as$v){$v>$s||$x="";$v>$p||$d="";$s+=$v;$p=$p*$v?:$v;}$z=$x.$d?"It.s a $x $d $z!":0;};
  • 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)
share|improve this answer
    
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. – insertusernamehere Jan 21 at 10:46
    
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 – aross Jan 21 at 11:55
2  
@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. – Martin Ender Jan 21 at 12:36
    
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. – insertusernamehere Jan 21 at 12:36
    
My script would work with register_globals, but I'll write future golfs as a function instead. Why oh why was short_closures rejected? – aross Jan 21 at 13:18

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")
}
share|improve this answer

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!"
share|improve this answer

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

share|improve this answer
    
I don't know AWK, could anyone explain why this was downvoted? – Alexander Revo Jan 19 at 21:57
    
Wasn't me, but I'd like an explanation of the code. Idk AWK either. – mbomb007 Jan 19 at 22:40
    
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. – Dennis Jan 19 at 23:40
    
To test try: echo 1 2 6 | <the above code> – Robert Benson Jan 20 at 13:08
2  
@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. – Stefano Sanfilippo Jan 20 at 14:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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