List into list

hi
thanks this site help me to improve my knowledge in julia, so

function pair_sum(nums, target)
#Given nums = [2, 7, 11, 15], target = 9,

d = Dict()
output = Int[]
count =0
for i in nums
    component = target - i
    res = []
    if component in keys(d)
        push!(res,component)
        push!(res,i)
        d[component] -=1
        append!(output,Tuple(res))
        count +=1
    else
        d[i] = 1
    end
end
println(count)
return output
end
nums = [2, 7, 11, 15 , 4 ,5]
target = 9
println("Total pairs   " , pair_sum(nums,target))

this code is work fine, but the output is

[2,7,4,5]

what i need is

[[2,7] , [4,5]]

list into list

Compare the type of your output to what you say you want: [[2,7] , [4,5]]

the type for output is

Array{Int64,1}
[2, 7, 4, 5]

and if i remove the int from

Array{Any,1}
Any[2, 7, 4, 5]

but what i need is

[[2,7],[4,5]]

Yes. Your code outputs an array of Int. What does your needed output look like? Does it look like an array of Ints, or an array of something else?

If you need pairs of 2, use a Tuple inside the Vector:
output = Tuple{Int,Int}[]
(If the length is unknown, use Vector{Int}[])

Now, use
push!(output, (3,4))
to append a single item, or
append!(output, [(3,4),(5,6),(7,8)])
to append a number of items

2 Likes

yes! that what i look for
thanks a lot

Hello @Faud_Sami, I see you are learning more and more! (Maybe translating more Python code as well :wink:)
Here are a couple of other ideas for this function:

# the original, pared down a bit
function pair_sum(nums, target)
    d = Set()
    output = NTuple{2, eltype(nums)}[]
    for x in nums
        y = target - x
        if y in d
            push!(output, (x, y))
        else
            push!(d, x)
        end
    end
    return output
end

# the same idea, more "direct"
# might want to ensure `nums` is unique for this
# or you'll have repeats
function pair_sum2(nums, target)
    N = length(nums)
    output = []
    for i in 1:N, j in (i+1):N
        if nums[i] + nums[j] == target
            push!(output, (nums[i], nums[j]))
        end
    end
    output
end

# if you don't care about repeats like (2, 7) and (7, 2)
pair_sum3(nums, y) = [(x, y-x) for x in nums if y-x in nums]

And their benchmarks

julia> nums = unique(rand(1:500, 100));

julia> target = rand(1:600)
579

julia> @btime pair_sum($nums, Ref(target)[])
  10.951 μs (18 allocations: 4.50 KiB)
10-element Array{Tuple{Int64,Int64},1}:
 (331, 248)
 (429, 150)
 (152, 427)
 (161, 418)
 (300, 279)
 (426, 153)
 (334, 245)
 (277, 302)
 (85, 494)
 (188, 391)

julia> @btime pair_sum2($nums, Ref(target)[]);
  5.203 μs (16 allocations: 704 bytes)

julia> @btime pair_sum3($nums, Ref(target)[]);
  5.134 μs (11 allocations: 1.30 KiB)
2 Likes

amazing !
this help :slight_smile:

function pair_sum(nums, target)
    filter(pair -> sum(pair) == target, collect(Iterators.partition(nums, 2)))
end

@info pair_sum([2, 7, 11, 15, 4, 5], 9) == [[2, 7], [4, 5]]
1 Like
filter(pair -> sum(pair) == target, collect(Iterators.partition(nums, 2)))

Note this only works if the pairs are consecutive and start on an odd index. (1=>2), (5=>6), which I think should be considered an edge case, not the general expected one.

julia> pair_sum([2, 7, 11, 15, 4, 5], 9)
2-element Array{SubArray{Int64,1,Array{Int64,1},Tuple{UnitRange{Int64}},true},1}:
 [2, 7]
 [4, 5]

julia> pair_sum([2, 7, 11, 15, 8, 4, 5], 9)
1-element Array{SubArray{Int64,1,Array{Int64,1},Tuple{UnitRange{Int64}},true},1}:
 [2, 7]

in that case, needs https://github.com/JuliaCollections/IterTools.jl

using IterTools
function pair_sum(nums, target)
    filter(pair -> sum(pair) == target, collect.(IterTools.partition(nums, 2, 1)))
end

@info pair_sum([2, 7, 11, 15, 4, 5], 9) == [[2, 7], [4, 5]]
@info pair_sum([2, 7, 11, 15, 8, 4, 5], 9) == [[2, 7], [4, 5]]

The pairs still have to be consecutive.

julia> pair_sum([2, 7, 11, 15, 4, 5], 9)
2-element Array{Array{Int64,1},1}:
 [2, 7]
 [4, 5]

julia> pair_sum([2, 7, 11, 15, 4, 100, 5], 9)
1-element Array{Array{Int64,1},1}:
 [2, 7]

It’s also much slower :flushed:

julia> @btime pair_sum($nums, Ref(target)[]);
  49.949 μs (708 allocations: 47.92 KiB)

julia> @btime pair_sum2($nums, Ref(target)[]);
  7.510 μs (86 allocations: 4.66 KiB)

This will cause the function to return a vector of Any:

julia> pair_sum2(nums, target)
2-element Array{Any,1}:
 (2, 7)
 (4, 5)

which is probably not what you want, and which has a performance penalty (though it is surprisingly small in this particular case.)

You should be wary of assignments that look like x = [], they signal performance issues. You could for example write

output = NTuple{2,eltype(nums)}[]

instead.

2 Likes