Find first missing positive: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Python}}: Added a solution in Python.)
(J)
Line 300: Line 300:
[3,4,-1,1] -> 2
[3,4,-1,1] -> 2
[7,8,9,11,12] -> 1</pre>
[7,8,9,11,12] -> 1</pre>

=={{header|J}}==
{{works with|J version 9.2 and later}}
{{trans|APL}}

<lang J>fmp=: {{ {.y-.~1+i.1+>./y }}S:0</lang>

Example use:

<lang J> fmp 1 2 0;3 4 _1 1; 7 8 9 11 12
3 2 1</lang>


=={{header|jq}}==
=={{header|jq}}==

Revision as of 22:57, 26 September 2021

Find first missing positive is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

Given an integer array nums   (which may or may not be sorted),   find the smallest missing positive integer.


Example
  •    nums  =   [1,2,0], [3,4,-1,1], [7,8,9,11,12]
  •   output =   3, 2, 1



APL

Works with: Dyalog APL

<lang APL>fmp ← ⊃(⍳1+⌈/)~⊢</lang>

Output:
      fmp¨ (1 2 0) (3 4 ¯1 1) (7 8 9 11 12)
3 2 1

AppleScript

<lang applescript>local output, aList, n set output to {} repeat with aList in {{1, 2, 0}, {3, 4, -1, 1}, {7, 8, 9, 11, 12}}

   set n to 1
   repeat while (aList contains n)
       set n to n + 1
   end repeat
   set end of output to n

end repeat return output</lang>

Output:

<lang applescript>{3, 2, 1}</lang>

AutoHotkey

<lang AutoHotkey>First_Missing_Positive(obj){

   Arr := [], i := 0
   for k, v in obj
       Arr[v] := true
   while (++i<Max(obj*))
       if !Arr[i]{
           m := i
           break
       }
   m := m ? m : Max(obj*) + 1
   return m>0 ? m : 1

}</lang> Examples:<lang AutoHotkey>nums := [[1,2,0], [3,4,-1,1], [7,8,9,11,12], [-4,-2,-3], []] for i, obj in nums{

   m := First_Missing_Positive(obj)
   output .= m ", "

} MsgBox % Trim(output, ", ") return</lang>

Output:
3, 2, 1, 1, 1

AWK

<lang AWK>

  1. syntax: GAWK -f FIND_FIRST_MISSING_POSITIVE.AWK

BEGIN {

   PROCINFO["sorted_in"] = "@ind_num_asc"
   nums = "[1,2,0],[3,4,-1,1],[7,8,9,11,12]"
   printf("%s : ",nums)
   n = split(nums,arr1,"],?") - 1
   for (i=1; i<=n; i++) {
     gsub(/[\[\]]/,"",arr1[i])
     split(arr1[i],arr2,",")
     for (j in arr2) {
       arr3[arr2[j]]++
     }
     for (j in arr3) {
       if (j <= 0) {
         continue
       }
       if (!(1 in arr3)) {
         ans = 1
         break
       }
       if (!(j+1 in arr3)) {
         ans = j + 1
         break
       }
     }
     printf("%d ",ans)
     delete arr3
   }
   printf("\n")
   exit(0)

} </lang>

Output:
[1,2,0],[3,4,-1,1],[7,8,9,11,12] : 3 2 1

BASIC

<lang basic>10 DEFINT A-Z: DIM D(100) 20 READ X 30 FOR A=1 TO X 40 READ N 50 FOR I=1 TO N 60 READ D(I) 70 PRINT D(I); 80 NEXT I 90 PRINT "==>"; 100 M=1 110 FOR I=1 TO N 120 IF M<D(I) THEN M=D(I) 130 NEXT I 140 FOR I=1 TO M+1 150 FOR J=1 TO N 160 IF D(J)=I GOTO 200 170 NEXT J 180 PRINT I 190 GOTO 210 200 NEXT I 210 NEXT A 220 DATA 3 230 DATA 3, 1,2,0 240 DATA 4, 3,4,-1,1 250 DATA 5, 7,8,9,11,12</lang>

Output:
 1  2  0 ==> 3
 3  4 -1  1 ==> 2
 7  8  9  11  12 ==> 1

BCPL

<lang bcpl>get "libhdr"

let max(v, n) = valof $( let x = !v

   for i=1 to n-1
       if x<v!i do x := v!i
   resultis x

$)

let contains(v, n, el) = valof $( for i=0 to n-1

       if v!i=el resultis true
   resultis false

$)

let fmp(v, n) = valof

   for i=1 to max(v,n)+1
       unless contains(v,n,i) resultis i

let show(len, v) be $( for i=0 to len-1 do writef("%N ", v!i)

   writef("==> %N*N", fmp(v, len))

$)

let start() be $( show(3, table 1,2,0)

   show(4, table 3,4,-1,1)
   show(5, table 7,8,9,11,12)

$)</lang>

Output:
1 2 0 ==> 3
3 4 -1 1 ==> 2
7 8 9 11 12 ==> 1

BQN

<lang bqn>FMP ← ⊢(⊑(¬∊˜ )/⊢)1+(↕1+⌈´)

FMP¨ ⟨⟨1,2,0⟩,⟨3,4,¯1,1⟩,⟨7,8,9,11,12⟩⟩</lang>

Output:
⟨ 3 2 1 ⟩

F#

<lang fsharp> // Find first missing positive. Nigel Galloway: February 15., 2021 let fN g=let g=0::g|>List.filter((<) -1)|>List.sort|>List.distinct

        match g|>List.pairwise|>List.tryFind(fun(n,g)->g>n+1) with Some(n,_)->n+1 |_->List.max g+1

[[1;2;0];[3;4;-1;1];[7;8;9;11;12]]|>List.iter(fN>>printf "%d "); printfn "" </lang>

Output:
3 2 1

Factor

<lang factor>USING: formatting fry hash-sets kernel math sequences sets ;

first-missing ( seq -- n )
   >hash-set 1 swap '[ dup _ in? ] [ 1 + ] while ;

{ { 1 2 0 } { 3 4 1 1 } { 7 8 9 11 12 } { 1 2 3 4 5 } { -6 -5 -2 -1 } { 5 -5 } { -2 } { 1 } { } } [ dup first-missing "%u ==> %d\n" printf ] each</lang>

Output:
{ 1 2 0 } ==> 3
{ 3 4 1 1 } ==> 2
{ 7 8 9 11 12 } ==> 1
{ 1 2 3 4 5 } ==> 6
{ -6 -5 -2 -1 } ==> 1
{ 5 -5 } ==> 1
{ -2 } ==> 1
{ 1 } ==> 2
{ } ==> 1

Go

Translation of: Wren

<lang go>package main

import (

   "fmt"
   "sort"

)

func firstMissingPositive(a []int) int {

   var b []int
   for _, e := range a {
       if e > 0 {
           b = append(b, e)
       }
   }
   sort.Ints(b)
   le := len(b)
   if le == 0 || b[0] > 1 {
       return 1
   }
   for i := 1; i < le; i++ {
       if b[i]-b[i-1] > 1 {
           return b[i-1] + 1
       }
   }
   return b[le-1] + 1

}

func main() {

   fmt.Println("The first missing positive integers for the following arrays are:\n")
   aa := [][]int{
       {1, 2, 0}, {3, 4, -1, 1}, {7, 8, 9, 11, 12}, {1, 2, 3, 4, 5},
       {-6, -5, -2, -1}, {5, -5}, {-2}, {1}, {}}
   for _, a := range aa {
       fmt.Println(a, "->", firstMissingPositive(a))
   }

}</lang>

Output:
The first missing positive integers for the following arrays are:

[1 2 0] -> 3
[3 4 -1 1] -> 2
[7 8 9 11 12] -> 1
[1 2 3 4 5] -> 6
[-6 -5 -2 -1] -> 1
[5 -5] -> 1
[-2] -> 1
[1] -> 2
[] -> 1

Haskell

Translation of: Wren

<lang Haskell>import Data.List (sort)

task :: Integral a => [a] -> a task = go . (0 :) . sort . filter (> 0)

 where
   go [x] = succ x
   go (w : xs@(x : _))
     | x == succ w = go xs
     | otherwise = succ w


main :: IO () main =

 print $
   map
     task
     [[1, 2, 0], [3, 4, -1, 1], [7, 8, 9, 11, 12]]</lang>
Output:
[3,2,1]


Or, expressed in terms of an infinite list, and standard library functions: <lang haskell>import Data.List (find, notElem) import Data.Maybe (fromJust)


FIRST MISSING POSITIVE NATURAL NUMBER ---------

firstGap :: [Int] -> Int firstGap xs = fromJust $ find (`notElem` xs) [1 ..]



TEST -------------------------

main :: IO () main =

 mapM_ putStrLn $
   fmap
     (\xs -> show xs <> " -> " <> (show . firstGap) xs)
     [ [1, 2, 0],
       [3, 4, -1, 1],
       [7, 8, 9, 11, 12]
     ]</lang>
Output:
[1,2,0] -> 3
[3,4,-1,1] -> 2
[7,8,9,11,12] -> 1

J

Translation of: APL

<lang J>fmp=: {{ {.y-.~1+i.1+>./y }}S:0</lang>

Example use:

<lang J> fmp 1 2 0;3 4 _1 1; 7 8 9 11 12 3 2 1</lang>

jq

Works with: jq

Works with gojq, the Go implementation of jq

In case the target array is very long, it probably makes sense either to sort it, or to use a hash, for quick lookup. For the sake of illustration, we'll use a hash: <lang jq>

  1. input: an array of integers

def first_missing_positive:

 INDEX(.[]; tostring) as $dict
 | first(range(1; infinite)
         | . as $n

| select($dict|has($n|tostring)|not) ) ;

def examples:

[1,2,0], [3,4,-1,1], [7,8,9,11,12], [-5, -2, -6, -1];
  1. The task:

examples | "\(first_missing_positive) is missing from \(.)"</lang>

Output:
3 is missing from [1,2,0]
2 is missing from [3,4,-1,1]
1 is missing from [7,8,9,11,12]
1 is missing from [-5,-2,-6,-1]

Julia

<lang julia> for array in [[1,2,0], [3,4,-1,1], [7,8,9,11,12], [-5, -2, -6, -1]]

   for n in 1:typemax(Int)
       !(n in array) && (println("$array  =>  $n"); break)
   end

end

</lang>

Output:
[1, 2, 0]  =>  3
[3, 4, -1, 1]  =>  2
[7, 8, 9, 11, 12]  =>  1
[-5, -2, -6, -1]  =>  1

Nim

Translation of: Julia

In order to avoid the O(n) search in arrays, we could use an intermediate set built from the sequence. But this is useless with the chosen examples.

<lang Nim>for a in [@[1, 2, 0], @[3, 4, -1, 1], @[7, 8, 9, 11, 12], @[-5, -2, -6, -1]]:

 for n in 1..int.high:
   if n notin a:
     echo a, " → ", n
     break</lang>
Output:
@[1, 2, 0] → 3
@[3, 4, -1, 1] → 2
@[7, 8, 9, 11, 12] → 1
@[-5, -2, -6, -1] → 1

Perl

<lang perl>#!/usr/bin/perl -l

use strict; use warnings; use List::Util qw( first );

my @tests = ( [1,2,0], [3,4,-1,1], [7,8,9,11,12],

 [3, 4, 1, 1], [1, 2, 3, 4, 5], [-6, -5, -2, -1], [5, -5], [-2], [1], []);

for my $test ( @tests )

 {
 print "[ @$test ]  ==>  ",
   first { not { map { $_ => 1 } @$test }->{$_}  } 1 .. @$test + 1;
 }</lang>
Output:
[ 1 2 0 ]  ==>  3
[ 3 4 -1 1 ]  ==>  2
[ 7 8 9 11 12 ]  ==>  1
[ 3 4 1 1 ]  ==>  2
[ 1 2 3 4 5 ]  ==>  6
[ -6 -5 -2 -1 ]  ==>  1
[ 5 -5 ]  ==>  1
[ -2 ]  ==>  1
[ 1 ]  ==>  2
[  ]  ==>  1

Phix

<lang Phix>procedure test(sequence s)

   for missing=1 to length(s)+1 do
       if not find(missing,s) then
           printf(1,"%v -> %v\n",{s,missing})
           exit
       end if
   end for

end procedure papply({{1,2,0},{3,4,-1,1},{7,8,9,11,12},{1,2,3,4,5},{-6,-5,-2,-1},{5,-5},{-2},{1},{}} ,test)</lang>

Output:
{1,2,0} -> 3
{3,4,-1,1} -> 2
{7,8,9,11,12} -> 1
{1,2,3,4,5} -> 6
{-6,-5,-2,-1} -> 1
{5,-5} -> 1
{-2} -> 1
{1} -> 2
{} -> 1

Python

<lang python>First missing natural number

from itertools import count


  1. firstGap :: [Int] -> Int

def firstGap(xs):

   First natural number not found in xs
   return next(x for x in count(1) if x not in xs)


  1. ------------------------- TEST -------------------------
  2. main :: IO ()

def main():

   First missing natural number in each list
   print([
       firstGap(x) for x in [
           [1, 2, 0],
           [3, 4, -1, 1],
           [7, 8, 9, 11, 12]
       ]
   ])


  1. MAIN ---

if __name__ == '__main__':

   main()

</lang>

Output:
[3, 2, 1]

Raku

<lang perl6>say $_, " ==> ", (1..Inf).first( -> \n { n ∉ $_ } ) for [ 1, 2, 0], [3, 4, 1, 1], [7, 8, 9, 11, 12], [1, 2, 3, 4, 5], [-6, -5, -2, -1], [5, -5], [-2], [1], []</lang>

Output:
[1 2 0] ==> 3
[3 4 1 1] ==> 2
[7 8 9 11 12] ==> 1
[1 2 3 4 5] ==> 6
[-6 -5 -2 -1] ==> 1
[5 -5] ==> 1
[-2] ==> 1
[1] ==> 2
[] ==> 1

REXX

This REXX version doesn't need to sort the elements of the sets,   it uses an associated array. <lang ring>/*REXX program finds the smallest missing positive integer in a given list of integers. */ parse arg a /*obtain optional arguments from the CL*/ if a= | a="," then a= '[1,2,0] [3,4,-1,1] [7,8,9,11,12] [1,2,3,4,5]' ,

                        "[-6,-5,-2,-1]  [5,-5]  [-2]  [1]  []"    /*maybe use defaults.*/

say 'the smallest missing positive integer for the following sets is:' say

   do j=1  for words(a)                         /*process each set  in  a list of sets.*/
   set= translate( word(a, j), ,'],[')          /*extract   a   "  from "   "   "   "  */
   #= words(set)                                /*obtain the number of elements in set.*/
   @.= .                                        /*assign default value for set elements*/
          do k=1  for #;  x= word(set, k)       /*obtain a set element  (an integer).  */
          @.x= x                                /*assign it to a sparse array.         */
          end   /*k*/
          do m=1  for #  until @.m==.           /*now, search for the missing integer. */
          end   /*m*/
   if @.m==  then m= 1                        /*handle the case of a  "null"  set.   */
   say right( word(a, j), 40)   ' ───► '   m    /*show the set and the missing integer.*/
   end          /*j*/                           /*stick a fork in it,  we're all done. */</lang>
output   when using the default inputs:
the smallest missing positive integer for the following sets is:

                                 [1,2,0]  ───►  3
                              [3,4,-1,1]  ───►  2
                           [7,8,9,11,12]  ───►  1
                             [1,2,3,4,5]  ───►  6
                           [-6,-5,-2,-1]  ───►  1
                                  [5,-5]  ───►  1
                                    [-2]  ───►  1
                                     [1]  ───►  2
                                      []  ───►  1

Ring

<lang ring> nums = [[1,2,0],[3,4,-1,1],[7,8,9,11,12]] numnr = list(3) numnr[1] = "[1,2,0]" numnr[2] = "[3,4,-1,1]" numnr[3] = "[7,8,9,11,12]"

for n = 1 to len(nums)

   sortNums = sort(nums[n])
   ln = len(sortNums)
   num = sortNums[ln]   
   for m = 1 to num + 1
       ind = find(nums[n],m)
       if ind < 1
          see "the smallest missing positive integer for " + numnr[n] + ": " + m + nl
          exit
       ok
   next

next </lang>

Output:
the smallest missing positive integer for [1,2,0]: 3
the smallest missing positive integer for [3,4,-1,1]: 2
the smallest missing positive integer for [7,8,9,11,12]: 1

Wren

Library: Wren-sort

<lang ecmascript>import "/sort" for Sort

var firstMissingPositive = Fn.new { |a|

   var b = a.where { |i| i > 0 }.toList
   Sort.insertion(b)
   if (b.isEmpty || b[0] > 1) return 1
   var i = 1
   while (i < b.count) {
       if (b[i] - b[i-1] > 1) return b[i-1] + 1
       i = i + 1    
   }
   return b[-1] + 1

}

System.print("The first missing positive integers for the following arrays are:\n") var aa = [

   [ 1, 2, 0], [3, 4, -1, 1], [7, 8, 9, 11, 12], [1, 2, 3, 4, 5],
   [-6, -5, -2, -1], [5, -5], [-2], [1], []

] for (a in aa) System.print("%(a) -> %(firstMissingPositive.call(a))")</lang>

Output:
The first missing positive integers for the following arrays are:

[1, 2, 0] -> 3
[3, 4, -1, 1] -> 2
[7, 8, 9, 11, 12] -> 1
[1, 2, 3, 4, 5] -> 6
[-6, -5, -2, -1] -> 1
[5, -5] -> 1
[-2] -> 1
[1] -> 2
[] -> 1