Exactly three adjacent 3 in lists: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 93: Line 93:
=={{header|Haskell}}==
=={{header|Haskell}}==
<lang haskell>import Data.Bifunctor (bimap)
<lang haskell>import Data.Bifunctor (bimap)
import Data.List (elemIndex)
import Data.List (span)


nnPeers :: Int -> [Int] -> Bool
nnPeers :: Int -> [Int] -> Bool
nnPeers n xs = maybe False go (elemIndex n xs)
nnPeers n xs =
uncurry (&&) $
bimap
(p . length)
(not . any p)
(span p (dropWhile (not . p) xs))
where
where
p = (n ==)
p x = n == x
go i =
uncurry (&&) $
bimap
(((&&) . p . length) <*> all p)
(not . any p)
(splitAt n (drop i xs))


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

Revision as of 18:08, 7 December 2021

Exactly three adjacent 3 in lists 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 5 lists of ints:
list[1] = [9,3,3,3,2,1,7,8,5]
list[2] = [5,2,9,3,3,7,8,4,1]
list[3] = [1,4,3,6,7,3,8,3,2]
list[4] = [1,2,3,4,5,6,7,8,9]
list[5] = [4,6,8,7,2,3,3,3,1]

Print 'true' if the value '3' appears in the list exactly 3 times and they are adjacent ones otherwise print 'false'.

ALGOL 68

Including the extra test cases from the Raku and Wren samples. <lang algol68>BEGIN # test lists contain exactly 3 threes and that they are adjacent #

   []INT   list1 = ( 9, 3, 3, 3, 2, 1, 7, 8, 5 ); # task test case  #
   []INT   list2 = ( 5, 2, 9, 3, 3, 7, 8, 4, 1 ); #   "    "    "   #
   []INT   list3 = ( 1, 4, 3, 6, 7, 3, 8, 3, 2 ); #   "    "    "   #
   []INT   list4 = ( 1, 2, 3, 4, 5, 6, 7, 8, 9 ); #   "    "    "   #
   []INT   list5 = ( 4, 6, 8, 7, 2, 3, 3, 3, 1 ); #   "    "    "   #
   []INT   list6 = ( 3, 3, 3, 1, 2, 4, 5, 1, 3 ); # additional test from the Raku/Wren sample #
   []INT   list7 = ( 0, 3, 3, 3, 3, 7, 2, 2, 6 ); # additional test from the Raku/Wren sample #
   []INT   list8 = ( 3, 3, 3, 3, 3, 4, 4, 4, 4 ); # additional test from the Raku/Wren sample #
   [][]INT lists = ( list1, list2, list3, list4, list5, list6, list7, list8 );
   FOR l pos FROM LWB lists TO UPB lists DO
       []INT list       = lists[ l pos ];
       INT   threes    := 0;  # number of threes in the list #
       INT   three pos := 0;  # position of the last three in the list #
       BOOL  list ok   := FALSE;
       FOR e pos FROM LWB list TO UPB list DO
           IF list[ e pos ] = 3 THEN
               threes   +:= 1;
               three pos := e pos
           FI
       OD;
       IF threes = 3 THEN
           # exactly 3 threes - check they are adjacent #
           list ok := ( list[ three pos - 1 ] = 3 AND list[ three pos - 2 ] = 3 )
       FI;
       # show the result #
       print( ( "[" ) );
       FOR e pos FROM LWB list TO UPB list DO
           print( ( " ", whole( list[ e pos ], 0 ) ) )
       OD;
       print( ( " ] -> ", IF list ok THEN "true" ELSE "false" FI, newline ) )
   OD

END</lang>

Output:
[ 9 3 3 3 2 1 7 8 5 ] -> true
[ 5 2 9 3 3 7 8 4 1 ] -> false
[ 1 4 3 6 7 3 8 3 2 ] -> false
[ 1 2 3 4 5 6 7 8 9 ] -> false
[ 4 6 8 7 2 3 3 3 1 ] -> true
[ 3 3 3 1 2 4 5 1 3 ] -> false
[ 0 3 3 3 3 7 2 2 6 ] -> false
[ 3 3 3 3 3 4 4 4 4 ] -> false

FreeBASIC

<lang freebasic>dim as integer list(1 to 5, 1 to 9) = {_

    {9,3,3,3,2,1,7,8,5}, {5,2,9,3,3,7,8,4,1},_
    {1,4,3,6,7,3,8,3,2}, {1,2,3,4,5,6,7,8,9},_
    {4,6,8,7,2,3,3,3,1}}
    

dim as boolean go, pass dim as integer i, j, c

for i = 1 to 5

   go = false
   pass = true
   c = 0
   for j = 1 to 9
       if list(i, j) = 3 then
           c+=1
           go = true
       else
           if go = true and c<>3 then pass=false
           go = false
       end if
   next j
   print i;"   ";
   if c = 3 and pass then print true else print false

next i</lang>

Output:

1   true
2   false
3   false
4   false
5   true

Haskell

<lang haskell>import Data.Bifunctor (bimap) import Data.List (span)

nnPeers :: Int -> [Int] -> Bool nnPeers n xs =

 uncurry (&&) $
   bimap
     (p . length)
     (not . any p)
     (span p (dropWhile (not . p) xs))
 where
   p x = n == x

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

main :: IO () main =

 putStrLn $
   unlines $
     (\xs -> show xs <> " -> " <> show (nnPeers 3 xs))
       <$> [ [9, 3, 3, 3, 2, 1, 7, 8, 5],
             [5, 2, 9, 3, 3, 7, 8, 4, 1],
             [1, 4, 3, 6, 7, 3, 8, 3, 2],
             [1, 2, 3, 4, 5, 6, 7, 8, 9],
             [4, 6, 8, 7, 2, 3, 3, 3, 1]
           ]</lang>
Output:
[9,3,3,3,2,1,7,8,5] -> True
[5,2,9,3,3,7,8,4,1] -> False
[1,4,3,6,7,3,8,3,2] -> False
[1,2,3,4,5,6,7,8,9] -> False
[4,6,8,7,2,3,3,3,1] -> True

JavaScript

<lang javascript>(() => {

   "use strict";
   // ------- N INSTANCES OF N AND ALL CONTIGUOUS -------
   // nnPeers :: Int -> [Int] -> Bool
   const nnPeers = n =>
       // True if xs contains exactly n instances of n
       // and the instances are all contiguous.
       xs => {
           const
               p = x => n === x,
               mbi = xs.findIndex(p);
           return -1 !== mbi ? (() => {
               const
                   rest = xs.slice(mbi),
                   sample = rest.slice(0, n);
               return n === sample.length && (
                   sample.every(p) && (
                       !rest.slice(n).some(p)
                   )
               );
           })() : false;
       };
   // ---------------------- TEST -----------------------
   const main = () => [
           [9, 3, 3, 3, 2, 1, 7, 8, 5],
           [5, 2, 9, 3, 3, 7, 8, 4, 1],
           [1, 4, 3, 6, 7, 3, 8, 3, 2],
           [1, 2, 3, 4, 5, 6, 7, 8, 9],
           [4, 6, 8, 7, 2, 3, 3, 3, 1]
       ]
       .map(
           xs => `${JSON.stringify(xs)} -> ${nnPeers(3)(xs)}`
       )
       .join("\n");
   return main();

})();</lang>

Output:
[9,3,3,3,2,1,7,8,5] -> true
[5,2,9,3,3,7,8,4,1] -> false
[1,4,3,6,7,3,8,3,2] -> false
[1,2,3,4,5,6,7,8,9] -> false
[4,6,8,7,2,3,3,3,1] -> true

Julia

<lang julia>function onlyconsecutivein(a::Vector{T}, lis::Vector{T}) where T

   return any(i -> a == lis[i:i+length(a)-1], 1:length(lis)-length(a)+1) &&
       count(x -> x == a[1], lis) == length(a)

end

needle = [3, 3, 3] for haystack in [

  [9,3,3,3,2,1,7,8,5],
  [5,2,9,3,3,7,8,4,1],
  [1,4,3,6,7,3,8,3,2],
  [1,2,3,4,5,6,7,8,9],
  [4,6,8,7,2,3,3,3,1]]
   println("$needle in $haystack: ", onlyconsecutivein(needle, haystack))

end </lang>

Perl

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

use strict; # https://rosettacode.org/wiki/Exactly_three_adjacent_3_in_lists use warnings;

my @lists = (

 [9,3,3,3,2,1,7,8,5],
 [5,2,9,3,3,7,8,4,1],
 [1,4,3,6,7,3,8,3,2],
 [1,2,3,4,5,6,7,8,9],
 [4,6,8,7,2,3,3,3,1]);

for my $ref ( @lists )

 {
 my @n = grep $ref->[$_] == 3, 0 .. $#$ref;
 print "@$ref => ",
   @n == 3 && $n[0] == $n[1] - 1 && $n[1] == $n[2] - 1 ? 'true' : 'false',
   "\n";
 }</lang>
Output:
9 3 3 3 2 1 7 8 5 => true
5 2 9 3 3 7 8 4 1 => false
1 4 3 6 7 3 8 3 2 => false
1 2 3 4 5 6 7 8 9 => false
4 6 8 7 2 3 3 3 1 => true

Python

<lang python>N instances of N and all contiguous


  1. nnPeers :: Int -> [Int] -> Bool

def nnPeers(n):

   True if xs contains exactly n instances of n
      and all instances are contiguous.
   
   def p(x):
       return n == x
   def go(xs):
       mbi = findIndex(p)(xs)
       if None is mbi:
           return False
       else:
           rest = [p(x) for x in xs[mbi:]]
           return n <= len(rest) and all(rest[0:n]) and (
               not any(rest[n:])
           )
   return go


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

def main():

   Tests for N=3
   print(
       '\n'.join([
           f'{xs} -> {nnPeers(3)(xs)}' for xs in [
               [9, 3, 3, 3, 2, 1, 7, 8, 5],
               [5, 2, 9, 3, 3, 7, 8, 4, 1],
               [1, 4, 3, 6, 7, 3, 8, 3, 2],
               [1, 2, 3, 4, 5, 6, 7, 8, 9],
               [4, 6, 8, 7, 2, 3, 3, 3, 1]
           ]
       ])
   )


  1. ----------------------- GENERIC ------------------------
  1. findIndex :: (a -> Bool) -> [a] -> (None | Int)

def findIndex(p):

   Just the first index at which an
      element in xs matches p,
      or None if no elements match.
   
   def go(xs):
       try:
           return next(
               i for i, v in enumerate(xs) if p(v)
           )
       except StopIteration:
           return None
   return go


  1. MAIN ---

if __name__ == '__main__':

   main()</lang>
Output:
[9, 3, 3, 3, 2, 1, 7, 8, 5] -> True
[5, 2, 9, 3, 3, 7, 8, 4, 1] -> False
[1, 4, 3, 6, 7, 3, 8, 3, 2] -> False
[1, 2, 3, 4, 5, 6, 7, 8, 9] -> False
[4, 6, 8, 7, 2, 3, 3, 3, 1] -> True

Raku

Generalized <lang perl6>for 1 .. 4 -> $n {

   say "\nExactly $n {$n}s, and they are consecutive:";
   say .gist, ' ', lc (.Bag{$n} == $n) && ( so .rotor($n=>-($n - 1)).grep: *.all == $n ) for
   [9,3,3,3,2,1,7,8,5],
   [5,2,9,3,3,7,8,4,1],
   [1,4,3,6,7,3,8,3,2],
   [1,2,3,4,5,6,7,8,9],
   [4,6,8,7,2,3,3,3,1],
   [3,3,3,1,2,4,5,1,3],
   [0,3,3,3,3,7,2,2,6],
   [3,3,3,3,3,4,4,4,4]

}</lang>

Output:
Exactly 1 1s, and they are consecutive:
[9 3 3 3 2 1 7 8 5] true
[5 2 9 3 3 7 8 4 1] true
[1 4 3 6 7 3 8 3 2] true
[1 2 3 4 5 6 7 8 9] true
[4 6 8 7 2 3 3 3 1] true
[3 3 3 1 2 4 5 1 3] false
[0 3 3 3 3 7 2 2 6] false
[3 3 3 3 3 4 4 4 4] false

Exactly 2 2s, and they are consecutive:
[9 3 3 3 2 1 7 8 5] false
[5 2 9 3 3 7 8 4 1] false
[1 4 3 6 7 3 8 3 2] false
[1 2 3 4 5 6 7 8 9] false
[4 6 8 7 2 3 3 3 1] false
[3 3 3 1 2 4 5 1 3] false
[0 3 3 3 3 7 2 2 6] true
[3 3 3 3 3 4 4 4 4] false

Exactly 3 3s, and they are consecutive:
[9 3 3 3 2 1 7 8 5] true
[5 2 9 3 3 7 8 4 1] false
[1 4 3 6 7 3 8 3 2] false
[1 2 3 4 5 6 7 8 9] false
[4 6 8 7 2 3 3 3 1] true
[3 3 3 1 2 4 5 1 3] false
[0 3 3 3 3 7 2 2 6] false
[3 3 3 3 3 4 4 4 4] false

Exactly 4 4s, and they are consecutive:
[9 3 3 3 2 1 7 8 5] false
[5 2 9 3 3 7 8 4 1] false
[1 4 3 6 7 3 8 3 2] false
[1 2 3 4 5 6 7 8 9] false
[4 6 8 7 2 3 3 3 1] false
[3 3 3 1 2 4 5 1 3] false
[0 3 3 3 3 7 2 2 6] false
[3 3 3 3 3 4 4 4 4] true

Ring

<lang ring> see "working..." + nl

list = List(5) list[1] = [9,3,3,3,2,1,7,8,5] list[2] = [5,2,9,3,3,7,8,4,1] list[3] = [1,4,3,6,7,3,8,3,2] list[4] = [1,2,3,4,5,6,7,8,9] list[5] = [4,6,8,7,2,3,3,3,1]

for n = 1 to 5

   good = 0
   cnt = 0
   len = len(list[n])
   for p = 1 to len
       if list[n][p] = 3
          good++
       ok
   next
   if good = 3
      for m = 1 to len-2   
          if list[n][m] = 3 and list[n][m+1] = 3 and list[n][m+2] = 3
             cnt++
          ok
      next
   ok
   if cnt = 1
      see "" + n + " true" + nl
   else
      see "" + n + " false" + nl
   ok

next

see "done..." + nl </lang>

Output:
working...
1 true
2 false
3 false
4 false
5 true
done...

Wren

<lang ecmascript>var lists = [

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

] System.print("Exactly three adjacent 3's:") for (list in lists) {

   var threesCount = list.count { |n| n == 3 }
   var condition = false
   if (threesCount == 3) {
       var i = list.indexOf(3)
       condition = list[i+1] == 3 && list[i+2] == 3
   }
   System.print("%(list) -> %(condition)")

}</lang>

Output:
Exactly three adjacent 3's:
[9, 3, 3, 3, 2, 1, 7, 8, 5] -> true
[5, 2, 9, 3, 3, 7, 8, 4, 1] -> false
[1, 4, 3, 6, 7, 3, 8, 3, 2] -> false
[1, 2, 3, 4, 5, 6, 7, 8, 9] -> false
[4, 6, 8, 7, 2, 3, 3, 3, 1] -> true
[3, 3, 3, 1, 2, 4, 5, 1, 3] -> false
[0, 3, 3, 3, 3, 7, 2, 2, 6] -> false
[3, 3, 3, 3, 3, 4, 4, 4, 4] -> false

Or, more generally, replacing the above 'for' statement with this one: <lang ecmascript>for (d in 1..4) {

   System.print("Exactly %(d) adjacent %(d)'s:")
   for (list in lists) {
       var dCount = list.count { |n| n == d }
       var condition = false
       if (dCount == d) {
           if (d == 1) {
               condition = true
           } else {
               var i = list.indexOf(d)
               condition = list[i+1] == d
               if (d > 2) condition = condition && list[i+2] == d
               if (d > 3) condition = condition && list[i+3] == d
           }
       }
       System.print("%(list) -> %(condition)")
   }
   System.print()}</lang>
Output:
Exactly 1 adjacent 1's:
[9, 3, 3, 3, 2, 1, 7, 8, 5] -> true
[5, 2, 9, 3, 3, 7, 8, 4, 1] -> true
[1, 4, 3, 6, 7, 3, 8, 3, 2] -> true
[1, 2, 3, 4, 5, 6, 7, 8, 9] -> true
[4, 6, 8, 7, 2, 3, 3, 3, 1] -> true
[3, 3, 3, 1, 2, 4, 5, 1, 3] -> false
[0, 3, 3, 3, 3, 7, 2, 2, 6] -> false
[3, 3, 3, 3, 3, 4, 4, 4, 4] -> false

Exactly 2 adjacent 2's:
[9, 3, 3, 3, 2, 1, 7, 8, 5] -> false
[5, 2, 9, 3, 3, 7, 8, 4, 1] -> false
[1, 4, 3, 6, 7, 3, 8, 3, 2] -> false
[1, 2, 3, 4, 5, 6, 7, 8, 9] -> false
[4, 6, 8, 7, 2, 3, 3, 3, 1] -> false
[3, 3, 3, 1, 2, 4, 5, 1, 3] -> false
[0, 3, 3, 3, 3, 7, 2, 2, 6] -> true
[3, 3, 3, 3, 3, 4, 4, 4, 4] -> false

Exactly 3 adjacent 3's:
[9, 3, 3, 3, 2, 1, 7, 8, 5] -> true
[5, 2, 9, 3, 3, 7, 8, 4, 1] -> false
[1, 4, 3, 6, 7, 3, 8, 3, 2] -> false
[1, 2, 3, 4, 5, 6, 7, 8, 9] -> false
[4, 6, 8, 7, 2, 3, 3, 3, 1] -> true
[3, 3, 3, 1, 2, 4, 5, 1, 3] -> false
[0, 3, 3, 3, 3, 7, 2, 2, 6] -> false
[3, 3, 3, 3, 3, 4, 4, 4, 4] -> false

Exactly 4 adjacent 4's:
[9, 3, 3, 3, 2, 1, 7, 8, 5] -> false
[5, 2, 9, 3, 3, 7, 8, 4, 1] -> false
[1, 4, 3, 6, 7, 3, 8, 3, 2] -> false
[1, 2, 3, 4, 5, 6, 7, 8, 9] -> false
[4, 6, 8, 7, 2, 3, 3, 3, 1] -> false
[3, 3, 3, 1, 2, 4, 5, 1, 3] -> false
[0, 3, 3, 3, 3, 7, 2, 2, 6] -> false
[3, 3, 3, 3, 3, 4, 4, 4, 4] -> true

XPL0

<lang XPL0>func Check(L); \Return 'true' if three adjacent 3's int L, C, I, J; def Size = 9; \number of items in each List [C:= 0; for I:= 0 to Size-1 do

   if L(I) = 3 then [C:= C+1;  J:= I];

if C # 3 then return false; \must have exactly three 3's return L(J-1)=3 & L(J-2)=3; \the 3's must be adjacent ];

int List(5+1), I; [List(1):= [9,3,3,3,2,1,7,8,5];

List(2):= [5,2,9,3,3,7,8,4,1];
List(3):= [1,4,3,6,7,3,8,3,2];
List(4):= [1,2,3,4,5,6,7,8,9];
List(5):= [4,6,8,7,2,3,3,3,1];
for I:= 1 to 5 do
    [IntOut(0, I);
    Text(0, if Check(List(I)) then " true" else " false");
    CrLf(0);
    ];

]</lang>

Output:
1 true
2 false
3 false
4 false
5 true