59
\$\begingroup\$

Given a nonempty array of positive integers, "increment" it once as follows:

  • If all the array elements are equal, append a 1 to the end of the array. For example:

    [1] -> [1, 1]
    [2] -> [2, 1]
    [1, 1] -> [1, 1, 1]
    [3, 3, 3, 3, 3] -> [3, 3, 3, 3, 3, 1]
    
  • Else, increment the first element in the array that is the array's minimum value. For example:

    [1, 2] -> [2, 2]
    [2, 1] -> [2, 2]
    [3, 1, 1] -> [3, 2, 1] -> [3, 2, 2] -> [3, 3, 2] -> [3, 3, 3]
    [3, 4, 9, 3] -> [4, 4, 9, 3] -> [4, 4, 9, 4] -> [5, 4, 9, 4] -> [5, 5, 9, 4] -> ...
    

(Each -> represents one increment, which is all your program needs to do.)

Output the resulting incremented array.

The shortest code in bytes wins.

\$\endgroup\$
2
  • \$\begingroup\$ Does 0 count as positive integer \$\endgroup\$
    – Downgoat
    Nov 28, 2016 at 23:14
  • 33
    \$\begingroup\$ @Downgoat 0 is not ever positive on PPCG. If 0 was allowed, the term would be "non-negative" \$\endgroup\$ Nov 28, 2016 at 23:23

57 Answers 57

1
2
1
\$\begingroup\$

MATLAB, 69 67 bytes

function a=f(a);if~range(a)a=[a 1];else[~,j]=min(a);a(j)=a(j)+1;end

range(a) is non-zero if not all elements are equal, and [~,j]=min(a) assigns the index of the minimum value in a to j, defaulting to the first value it finds. Input is a row vector. Saved 2 bytes by reversing the if/else logic to get rid of some semicolons (else[~,j] is legal, but elsea=[a 1] is not).

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

Clojure, 112 100 bytes

Unfortunately min-key returns the last index of the smallest index, not the first one. This works for integer inputs and shorter arrays than 10^9 elements ;)

Edit: Defining an anonymous function, using (apply = a) instead of (= 1(count(set a))).

(fn[a](if(apply = a)(conj a 1)(update a(apply min-key #(+(nth a %)(* % 1e-9))(range(count a)))inc)))

Original:

(defn f[a](if(= 1(count(set a)))(conj a 1)(update a(apply min-key #(+(nth a %)(* % 1e-9))(range(count a)))inc)))

A less hacky 134-byte solution reverses the vector before updating it and then reverse it back again:

(defn f[a](if(= 1(count(set a)))(conj a 1)(let[r #(vec(reverse %))a(r a)](r(update a(apply min-key #(nth a %)(range(count a)))inc)))))
\$\endgroup\$
1
\$\begingroup\$

MATLAB, 66 53 bytes

if(range(a))[~,b]=min(a);a(b)=a(b)+1;else;a=[a 1];end

Output:

Initialize:

a = [3 2]

Successive runs:

[3 2] -> [3 3] -> [3 3 1] -> [3 3 2] -> [3 3 3] -> [3 3 3 1] ...
\$\endgroup\$
1
  • 2
    \$\begingroup\$ You cannot hardcode the inputs, you'd need to do something like @(x) …. \$\endgroup\$ Dec 14, 2017 at 2:12
1
\$\begingroup\$

SmileBASIC 3, 101 bytes

Defines a statement function I A where A is our integer array of numbers. Output is achieved by modifying the input (as arrays are references.)

DEF I A
M=MIN(A)IF M==MAX(A)THEN PUSH A,1RETURN
FOR C=0TO LEN(A)IF M==A[C]THEN INC A[C]BREAK
NEXT
END
\$\endgroup\$
1
  • \$\begingroup\$ You can save 2 bytes by replacing BREAK with M=0, because A can't contain 0 so M==A[C] will never be true. \$\endgroup\$
    – 12Me21
    Jun 5, 2018 at 19:02
1
\$\begingroup\$

SmileBASIC, 77 bytes

DEF I A
IF MIN(A)==MAX(A)THEN PUSH A,0
WHILE A[I]>MAX(A)I=I+1WEND
INC A[I]END
\$\endgroup\$
1
\$\begingroup\$

K (oK), 24 bytes

Solution:

{(x[x?&/x]+:1;x,1)1=#?x}

Try it online!

Explanation:

Nothing too fancy, potentially golfable further:

{(x[x?&/x]+:1;x,1)1=#?x} / the solution
{                      } / anonymous lambda taking implicit x argument
                     ?x  / get distinct values in x
                    #    / count length
                  1=     / is it 1?
 (           ;   )       / two item list which is index into
              x,1        / append 1 to input
  x[     ]+:1            / modify x in-place (add 1) at index given in []
      &/x                / minimum of x
    x?                   / lookup index (returns first one)
\$\endgroup\$
1
\$\begingroup\$

Vyxal, 10 bytes

≈[1J|g₌ḟ›Ȧ  # main program
≈           # all elements in input are equal
 [1J|g₌ḟ›Ȧ  # main if statement
  1J        # if true, append 1 to input
     g₌ḟ›Ȧ  # if false...
     g      # get the minimum
      ₌ḟ›   # push the index of the min and the increment of the min
         Ȧ  # set that index to the increment
            # implicit output

I came up with this independently but surprisingly it was pretty similar in structure to @AaronMiller's answer. Try it Online!

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

JavaScript, 55 bytes

a=>a.every(e=>e==a[0])?a.push(1):a.fill(Math.max(...a))

Modifies the array passed to it, otherwise, it's 3 bytes longer:

a=>a.every(e=>e==a[0])?a.push(1)&&a:a.fill(Math.max(...a))

Try it Online!

Explanation

a=>a.every          // Check that every element "e"...
  (e=>e==a[0])      // ...is equal to the first element.
    ?a.push(1)      // If it's the case push 1 at the end.
      :a.fill       // Else fill the entire array...
        (Math.max   // ...with the biggest...
          (...a))   // ...entry of the array.

Some notable parts

  • Checking the first element of the array is valid because all of the elements needs to be the same anyways
  • If the array have different elements, it will end up being an array filled with the largest number anyways, so let's do directly that
\$\endgroup\$
1
  • \$\begingroup\$ Looks like you're expected to only do one iterate [3, 4, 9, 3] -> [4, 4, 9, 3] not to the end \$\endgroup\$
    – l4m2
    Jan 28, 2023 at 8:07
1
\$\begingroup\$

PowerShell, 76 60 bytes

$x,$y=($a=$args)|sort -u
$a[$a.IndexOf(+$x)]+=!!$y
$a+,1*!$y

Try it online!

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

Uiua, 19 bytes

(⍜⊡'+1⊢⍏.|⊂∶1)≍↻1..

Try it!

(⍜⊡'+1⊢⍏.|⊂∶1)≍↻1..
                  .  # duplicate
              ≍↻1.   # are all elements equal?
(        |   )       # run the left part if not, or right part if so
          ⊂∶1        # append 1 to end
        .            # duplicate
      ⊢⍏             # index of minimum element
 ⍜⊡'+1               # increment value at that index
\$\endgroup\$
1
\$\begingroup\$

Wolfram Language (Mathematica), 50 bytes

If[Equal@@#,Append@1,1+#&~MapAt~#&@@Ordering@#]@#&

Try it online!

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

Uiua, 14 bytes

⬚0+⍘⊚?⧻⊢≍,⊃⍖⍏.

Try it online!

Finds the 0-based index to increment (or the length if the elements are all equal), and adds 1 at that index. The (rise; the indices in the array that would put the values in sorted order) is reused three times:

  • "all equal" test can be done with "rise matches fall"
  • "the first index of minimum element" is "first of rise"
  • "the length of the array" is the same as "the length of rise"
⬚0+⍘⊚?⧻⊢≍,⊃⍖⍏.    input: an array of positive integers A
            ⊃⍖⍏.   push fall(A), rise(A), A
          ≍,         keep rise(A) and evaluate "rise(A) == fall(A)"
      ?⧻⊢            if so, call length; otherwise call first on rise(A)
    ⍘⊚              inverse where; create an array B so that B[i] == count of i
                     (3 -> [0, 0, 0, 1])
⬚0+                  elementwise add the result to A, padding with zeros if needed
\$\endgroup\$
0
\$\begingroup\$

Pyth, 16 bytes

?tl{QXxQhSQQ1+Q1

A program that takes input of a list and prints the result.

Test suite

How it works

?tl{QXxQhSQQ1+Q1  Program. Input: Q
?                 If:
  l                The length
   {Q              of Q deduplicated
 t                 - 1
                   is non-zero:
     X     Q1       Increment in Q at index:
      xQ             Index in Q of
        h            the first element
         SQ          of Q sorted (minimum)
                  else:
             +     Append
               1   1
              Q    to Q
                   Implicitly print                    
\$\endgroup\$
0
\$\begingroup\$

Haskell, 93 bytes

f z|and$(==)<$>z<*>z=z++[1]|1>0=z#minimum z where(x:z)#m|x==m=x+1:z;(x:z)#m|1>0=x:z#m;[]#_=[]

Ungolfed:

incrementArray :: [Int] -> [Int]
incrementArray xs | and [x == y | x <- xs, y <- xs] = xs ++ [1]
                  | otherwise = g xs (minimum xs)
     where g (x:xs) m | x == m = (x + 1):xs
           g (x:xs) m | otherwise = x:g xs m
           g [] _ = []

Initial attempt, will try to come up with something more sophisticated later.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Why not make a separate function instead of using where? \$\endgroup\$ Nov 29, 2016 at 3:45
0
\$\begingroup\$

Wonder, 44 bytes

@[dp1unq#0?:=#[:0(iO f\min#0)#0+1f]#0?++#0 1

This is not what I had in mind when I made this language... It's literally worse than Perl in terms of readability!

Usage:

(@[dp1unq#0?:=#[:0(iO f\min#0)#0+1f]#0?++#0 1])[3 4 9 3]

Explanation

More readable:

@[
  dp 1 unq #0
    ? set #[
            get 0 (iO f\ min #0) #0
            + 1 f
           ] #0
    ? con #0 1
 ]

Basically checks if dropping 1 item from the unique subset of the argument makes the list empty. If not, then we increment the minimum of the array. Otherwise, we simply concatenate 1 to the argument.

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

Kotlin, 75 bytes

fun a(s:MutableList<Int>){if(s.toSet().size<2)s+=0;s[s.indexOf(s.min())]++}

Modifies the function argument.

Damn you strong typing! :MutableList<Int> accounts for 17 bytes alone. I don't think there is a solution where the type can be inferred, unfortunately.

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

jq, 44 characters

if unique[1]then.[index(min)]+=1else.+[1]end

Sample run (-c (--compact-output) option used only here for readability):

bash-4.3$ jq -c 'if unique[1]then.[index(min)]+=1else.+[1]end' <<< '[3,1,1]'
[3,2,1]

bash-4.3$ jq -c 'if unique[1]then.[index(min)]+=1else.+[1]end' <<< '[3,2,1]'
[3,2,2]

bash-4.3$ jq -c 'if unique[1]then.[index(min)]+=1else.+[1]end' <<< '[3,2,2]'
[3,3,2]

bash-4.3$ jq -c 'if unique[1]then.[index(min)]+=1else.+[1]end' <<< '[3,3,2]'
[3,3,3]

bash-4.3$ jq -c 'if unique[1]then.[index(min)]+=1else.+[1]end' <<< '[3,3,3]'
[3,3,3,1]

On-line test:

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

PHP, 79 bytes

function i($a){max($a)>($n=min($a))?$a[array_search($n,$a)]++:$a[]=1;return$a;}

I think this needs no explanation.

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

Groovy - 45 bytes

A groovy closure which accepts a list of Integer as input - please note this modifies the input List.

{o->(o-o[0])?o[o.indexOf(o.min())]+=1:o<<1;o}

Test cases can be seen here:

http://ideone.com/9vRd9e

Alternative of 56 bytes if the code needs to work with int[] or List<Integer>:

{o=it.toList();(o-o[0])?o[o.indexOf(o.min())]+=1:o<<1;o}

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

Actually, 18 bytes

The algorithm used in this answer is largely based on Dennis' Jelly answer. Golfing suggestions welcome! Try it online!

;;M@u#q;m@í0@α1@q¥

Ungolfing

      Implicit input a.
;;    Duplicate a twice.
M     Get the maximum of a.
@u#   Increment all of a and convert back to a list.
q;    Append max(a) to the end of a_plus_one, and duplicate. Call it b.
m@í   Get index of the minimum of b. Call it min_index.
        If all elements of a were equal, this is the maximum at the end.
        Else, it's somewhere else in the array.
0@α   Push a list of min_index zeroes.
1@q   Append a 1 to the end. Call this array c.
        This will increment at the desired index or otherwise append a 1.
¥     Pairwise add a and c to get our incremented array.
      Implicit return.
\$\endgroup\$
0
\$\begingroup\$

Tcl, 114 bytes

proc I a {if [llength [set S [lsort -u $a]]]<2 {lappend a 1} {lset a [lsearch $a [set m [lindex $S 0]]] [incr m]}}

Try it online!

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

Vim, 49 bytes

y$i,<esc>:s/^\(,\d*\)\1*$/&,0
/\<<C-r>=min([<C-r>"])
\>
f0<C-a>|x

Takes the array as comma-separated integers in the buffer. Try it online!

Explanation

y$i,<esc>

Yank the original list of integers; then insert an extra comma at the beginning.

:s/^\(,\d*\)\1*$/&,0<cr>

Using regex, determine if the entire line consists of the same number. If so, append ,0.

/\<...\><cr>

Find the first match of ... as a full word (\< and \> represent word boundaries, corresponding to \b in PCRE), where ... is:

<C-r>=min([<C-r>"])<cr>

Using the expression register, calculate the minimum of the original list.

If the original list was heterogeneous, the cursor is now on the number we want to increment. If the original list was all equal, however, we want to increment the 0 at the end, so:

f0

Move to the next occurrence of 0 on the line. If there is no 0, this does nothing.

<C-a>|x

Increment the number under the cursor. Go to the beginning of the line and delete the extra comma.

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

Factor, 77 bytes

[ dup all-eq? [ 1 suffix ] [ dup [ ] infimum-by* 1 + swap pick set-nth ] if ]

Try it online!

Went through a bunch of different iterations of this. tri was shorter than stack shufflers, amazingly, when using change-nth, but locals were king. However, we can attain even fewer bytes by using infimum-by*, which places both the index and value of the smallest element on the stack.

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

Julia 1.8, 44 bytes

!x=allequal(x) ? [x;1] : (x[argmin(x)]+=1;x)

Attempt This Online!

allequal requires julia 1.8 or later

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

Arturo, 60 56 bytes

$->a->([]=a--a\0)?->a++1[i:index a min a a\[i]:a\[i]+1a]

Try it

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

Scala, 159 bytes

Golfed version. Try it online!

a=>{def g(l:List[Int]):List[Int]=l match{case x::q if x==a.min=>(x+1)::q;case x::q=>x::g(q);case _=>Nil};if(a.distinct.length==1)a:+1 else g(a.toList).toArray}

Ungolfed version. Try it online!

object Main extends App {

  def incrementArray(arr: Array[Int]): Array[Int] = {
    val minVal = arr.min
    def g(list: List[Int], m: Int): List[Int] = list match {
      case x :: xs if x == m => (x + 1) :: xs
      case x :: xs           => x :: g(xs, m)
      case Nil               => Nil
    }
    if (arr.distinct.length == 1) arr :+ 1
    else g(arr.toList, minVal).toArray
  }

  var r = Array(3, 1, 1);
  for (i <- 1 to 10) {
    r = incrementArray(r)
    println(r.mkString(", "))
  }

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

Perl 5 -MList::Util=,reduce -pa, 75 68 bytes

$F[(grep$_-$F[0],@F)?reduce{$F[$a]>$F[$b]?$b:$a}0..$#F:@F]++;$_="@F"

Try it online!

\$\endgroup\$
1
2

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.