DEV Community

Discussion on: Daily Coding Puzzles - Oct 29th - Nov 2nd

Collapse
 
aspittel profile image
Ali Spittel

Monday

Count of positives / sum of negatives (8 KYU):

Return an array, where the first element is the count of positives numbers and the second element is sum of negative numbers.

link

Collapse
 
choroba profile image
E. Choroba
#! /usr/bin/perl
use warnings;
use strict;

use List::Util qw{ sum0 };

sub cpsn {
    return unless @_;
    my @neg = grep $_ <= 0, @_;
    return @_ - @neg, sum0(@neg)
}

use Test::More tests => 5;
is_deeply [cpsn()], [];
is_deeply [cpsn(-1)], [0, -1];
is_deeply [cpsn(0, 0)], [0, 0];
is_deeply [cpsn(2)], [1, 0];
is_deeply [cpsn(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -11, -12, -13, -14, -15)],
          [10, -65];
Collapse
 
thejessleigh profile image
jess unrein

Idk that this is an actual good Go solution - I'm not a Go expert so it can be hard for me to tell sometimes. It's so idiomatically verbose!

func Count(a []int) (r []int) {
    r = make([]int, 0)

    if len(a) == 0 {
        return
    }

    var pos int = 0
    var neg int = 0

    for _, item := range a {
        if item >= 0 {
            pos += 1
        } else {
            neg += item
        }
    }

    r = append(r, pos)
    return append(r, neg)
}
Collapse
 
dance2die profile image
Sung M. Kim • Edited

Solved it awhile ago (forgot about it).

Here is a C# answer.

using System.Linq;
using System;

public class Kata
{
    public static int[] CountPositivesSumNegatives(int[] a)
    {
        // guard clause for edge cases
        if (a == null || a.Length == 0) return new int[0];

        int count = 0;
        int sum = 0;
        // ".ToList()" is required to iterate the sequence
        a.Select(n => n > 0 ? count++ : sum += n).ToList();

        return new[] {count, sum};
    }
}

And just re-solved it using JavaScript

function countPositivesSumNegatives(input) {
    return (input && input.length >= 1) 
      ? input.reduce((acc, n) => {
          n > 0 ? acc[0]++ : acc[1] += n;
          return acc;
        }, [0, 0]) 
    : [];
}
Collapse
 
aspittel profile image
Ali Spittel

Refactored to the code-golfiest thing ever with help of @joshcheek !

const countPositivesSumNegatives=i=>(i||[]).reduce(([c=0,s=0],v)=>v>0?[++c,s]:[c,s+v],[])
Collapse
 
tux0r profile image
tux0r • Edited

The golfiest version would probably be in Dyalog APL - even with newlines:

A←1 2 3 ¯4 ¯5 ¯6
X←+/(~A<0)/A
Y←+/(~A>0)/A
O←X Y

Output:

    O
6 ¯15
Thread Thread
 
gypsydave5 profile image
David Wickes

I will one day be able to look at APL without my brain leaking out of my ears.

Today is not that day.

Thread Thread
 
tux0r profile image
tux0r

This was my first time trying to actually do something with it. It was fun and it still sucked my brains out. (Both of them.)

Thread Thread
 
joshcheek profile image
Josh Cheek • Edited

Oh holy shit! I was looking at it for several minutes and it started making sense! Maybe because I thought through problem with @aspittel , or maybe this APL is more sensible (the last one I saw, someone had spilled a bag of unicode across its source).

I'm using Ruby's comment syntax because IDK how to do it in APL

# Haskell uses arrows for assignment in `do` blocks.
# Whitespace delimited numbers are a thing in lisp.
# The high bar looks a lot like a minus sign, so:

A←                 # set into the variable A
A←1 2 3 ¯4 ¯5 ¯6   # the list of numbers: [1, 2, 3, -4, -5, -6]


# Haskell iplements + as a function that you can pass around
# The slash looks like and is used like a shell pipeline.
# Tilde is logical negation in many syntaxes.
# `A` in `A<0` is like SQL, which uses the
# table name to refer to that table's current row.

X←             # set into the variable X
X←+/           # the sum of
X←+/(~         # the numbers which aren't
X←+/(~A<0)/    # negative
X←+/(~A<0)/A   # from the list A

Y←            # set into the variable Y
Y←+/          # the sum of
Y←+/(~        # the variables that aren't
Y←+/(~A>0)/   # positive
Y←+/(~A>0)/A  # from the list A

O←X Y    # set X and Y as the output
Thread Thread
 
tux0r profile image
tux0r • Edited

maybe this APL is more sensible (the last one I saw, someone had spilled a bag of unicode across its source).

That's the thing with first tries: You mostly write code which is relatively easy to understand. The APL symbol for comments is , by the way. And I have no idea how to write it without a Unicode table. ;-)

Thank you for your explanation. I finally understand wtf I was doing. (I know that I could probably have obfuscated it even more, "not negative" is longer than "positive", but I think I still won.)

Collapse
 
bodonferenc profile image
Ferenc Bodon • Edited

Q/kdb+ solution (let l be the input list):

(sum l > 0; sum l where l < 0)
Collapse
 
kspeakman profile image
Kasey Speakman • Edited

F#

let update (count, sum) value =
    if value > 0 then (count + 1), sum
    else              count, (sum + value)

// usage, start with 0 count/sum, update them for each value
let (count, sum) = Array.fold update (0, 0) inputArr

This returns a tuple instead of an array, which I believe is an improvement.

Collapse
 
kaelscion profile image
kaelscion

Python 3 solution update. Posted to the wrong part of the discussion :P


def count_and_sum(arr, x):
    if not arr == None and len(arr) > 0:
        ct = len([i for i in arr if i > x])
        sum_neg = sum([i for i in arr if i <= x])
        return [ct, sum_neg]
    else:
        return([])
Collapse
 
sdicke profile image
Sebastian Martin Dicke

Haskell

countPositivesSumNegatives :: [Int] -> [Int]
countPositivesSumNegatives input =
    let positives = length $ filter (>= 0) input in
    let negatives = sum $ filter (<0) input in
    [positives, negatives]
Collapse
 
clandau profile image
Courtney

TypeScript

export function countPositivesSumNegatives(input: number[]) : number[] {
  let positiveCount = 0, negativeSum = 0;
  if(!input || !input.length) return [];
  for(let num of input) {
      if(num <= 0) negativeSum += num;
      else positiveCount++;
    }
  return [positiveCount, negativeSum];
}
Collapse
 
tux0r profile image
tux0r
(defun monday (in-param)
    (list
        ;; positive numbers:
        (apply #'+ (remove-if-not #'plusp in-param))

        ;; negative numbers:
        (apply #'+ (remove-if #'plusp in-param))))

Usage:

* (monday (list 1 2 5 -2 -7))

(8 -9)
Collapse
 
gypsydave5 profile image
David Wickes

Common Lisp FTW!