Display a linear combination

Revision as of 13:46, 10 October 2020 by BigL (talk | contribs)

Display a finite linear combination in an infinite vector basis .

Task
Display a linear combination
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Write a function that, when given a finite list of scalars ,
creates a string representing the linear combination in an explicit format often used in mathematics, that is:

where



The output must comply to the following rules:

  •   don't show null terms, unless the whole combination is null.
e(1)     is fine,     e(1) + 0*e(3)     or     e(1) + 0     is wrong.
  •   don't show scalars when they are equal to one or minus one.
e(3)     is fine,     1*e(3)     is wrong.
  •   don't prefix by a minus sign if it follows a preceding term.   Instead you use subtraction.
e(4) - e(5)     is fine,     e(4) + -e(5)     is wrong.


Show here output for the following lists of scalars:

 1)    1,  2,  3
 2)    0,  1,  2,  3
 3)    1,  0,  3,  4
 4)    1,  2,  0
 5)    0,  0,  0
 6)    0
 7)    1,  1,  1
 8)   -1, -1, -1
 9)   -1, -2,  0, -3
10)   -1



11l

Translation of: Python

<lang 11l>F linear(x)

  V a = enumerate(x).filter2((i, v) -> v != 0).map2((i, v) -> ‘#.e(#.)’.format(I v == -1 {‘-’} E I v == 1 {‘’} E String(v)‘*’, i + 1))
  R (I !a.empty {a} E [String(‘0’)]).join(‘ + ’).replace(‘ + -’, ‘ - ’)

L(x) [[1, 2, 3], [0, 1, 2, 3], [1, 0, 3, 4], [1, 2, 0], [0, 0, 0], [0], [1, 1, 1], [-1, -1, -1], [-1, -2, 0, 3], [-1]]

  print(linear(x))</lang>
Output:
e(1) + 2*e(2) + 3*e(3)
e(2) + 2*e(3) + 3*e(4)
e(1) + 3*e(3) + 4*e(4)
e(1) + 2*e(2)
0
0
e(1) + e(2) + e(3)
-e(1) - e(2) - e(3)
-e(1) - 2*e(2) + 3*e(4)
-e(1)

C

Accepts vector coefficients from the command line, prints usage syntax if invoked with no arguments. This implementation can handle floating point values but displays integer values as integers. All test case results shown with invocation. A multiplication sign is not shown between a coefficient and the unit vector when a vector is written out by hand ( i.e. human readable) and is thus not shown here as well. <lang C>

  1. include<stdlib.h>
  2. include<stdio.h>
  3. include<math.h> /*Optional, but better if included as fabs, labs and abs functions are being used. */

int main(int argC, char* argV[]) {

int i,zeroCount= 0,firstNonZero = -1; double* vector;

if(argC == 1){ printf("Usage : %s <Vector component coefficients seperated by single space>",argV[0]); }

else{

printf("Vector for ["); for(i=1;i<argC;i++){ printf("%s,",argV[i]); } printf("\b] -> ");


vector = (double*)malloc((argC-1)*sizeof(double));

for(i=1;i<=argC;i++){ vector[i-1] = atof(argV[i]); if(vector[i-1]==0.0) zeroCount++; if(vector[i-1]!=0.0 && firstNonZero==-1) firstNonZero = i-1; }

if(zeroCount == argC){ printf("0"); }

else{ for(i=0;i<argC;i++){ if(i==firstNonZero && vector[i]==1) printf("e%d ",i+1); else if(i==firstNonZero && vector[i]==-1) printf("- e%d ",i+1); else if(i==firstNonZero && vector[i]<0 && fabs(vector[i])-abs(vector[i])>0.0) printf("- %lf e%d ",fabs(vector[i]),i+1); else if(i==firstNonZero && vector[i]<0 && fabs(vector[i])-abs(vector[i])==0.0) printf("- %ld e%d ",labs(vector[i]),i+1); else if(i==firstNonZero && vector[i]>0 && fabs(vector[i])-abs(vector[i])>0.0) printf("%lf e%d ",vector[i],i+1); else if(i==firstNonZero && vector[i]>0 && fabs(vector[i])-abs(vector[i])==0.0) printf("%ld e%d ",vector[i],i+1); else if(fabs(vector[i])==1.0 && i!=0) printf("%c e%d ",(vector[i]==-1)?'-':'+',i+1); else if(i!=0 && vector[i]!=0 && fabs(vector[i])-abs(vector[i])>0.0) printf("%c %lf e%d ",(vector[i]<0)?'-':'+',fabs(vector[i]),i+1); else if(i!=0 && vector[i]!=0 && fabs(vector[i])-abs(vector[i])==0.0) printf("%c %ld e%d ",(vector[i]<0)?'-':'+',labs(vector[i]),i+1); } } }

free(vector);

return 0; } </lang>

Output:
C:\rossetaCode>vectorDisplay.exe 1 2 3
Vector for [1,2,3] -> e1 + 2 e2 + 3 e3
C:\rossetaCode>vectorDisplay.exe 0 0 0
Vector for [0,0,0] -> 0
C:\rossetaCode>vectorDisplay.exe 0 1 2 3
Vector for [0,1,2,3] -> e2 + 2 e3 + 3 e4
C:\rossetaCode>vectorDisplay.exe 1 0 3 4
Vector for [1,0,3,4] -> e1 + 3 e3 + 4 e4
C:\rossetaCode>vectorDisplay.exe 1 2 0
Vector for [1,2,0] -> e1 + 2 e2
C:\rossetaCode>vectorDisplay.exe 0 0 0
Vector for [0,0,0] -> 0
C:\rossetaCode>vectorDisplay.exe 0
Vector for [0] -> 0
C:\rossetaCode>vectorDisplay.exe 1 1 1
Vector for [1,1,1] -> e1 + e2 + e3
C:\rossetaCode>vectorDisplay.exe -1 -1 -1
Vector for [-1,-1,-1] -> - e1 - e2 - e3
C:\rossetaCode>vectorDisplay.exe -1 -2 0 -3
Vector for [-1,-2,0,-3] -> - e1 - 2 e2 - 3 e4
C:\rossetaCode>vectorDisplay.exe -1
Vector for [-1] -> - e1

C#

Translation of: D

<lang csharp>using System; using System.Collections.Generic; using System.Text;

namespace DisplayLinearCombination {

   class Program {
       static string LinearCombo(List<int> c) {
           StringBuilder sb = new StringBuilder();
           for (int i = 0; i < c.Count; i++) {
               int n = c[i];
               if (n < 0) {
                   if (sb.Length == 0) {
                       sb.Append('-');
                   } else {
                       sb.Append(" - ");
                   }
               } else if (n > 0) {
                   if (sb.Length != 0) {
                       sb.Append(" + ");
                   }
               } else {
                   continue;
               }
               int av = Math.Abs(n);
               if (av != 1) {
                   sb.AppendFormat("{0}*", av);
               }
               sb.AppendFormat("e({0})", i + 1);
           }
           if (sb.Length == 0) {
               sb.Append('0');
           }
           return sb.ToString();
       }
       static void Main(string[] args) {
           List<List<int>> combos = new List<List<int>>{
               new List<int> { 1, 2, 3},
               new List<int> { 0, 1, 2, 3},
               new List<int> { 1, 0, 3, 4},
               new List<int> { 1, 2, 0},
               new List<int> { 0, 0, 0},
               new List<int> { 0},
               new List<int> { 1, 1, 1},
               new List<int> { -1, -1, -1},
               new List<int> { -1, -2, 0, -3},
               new List<int> { -1},
           };
           foreach (List<int> c in combos) {
               var arr = "[" + string.Join(", ", c) + "]";
               Console.WriteLine("{0,15} -> {1}", arr, LinearCombo(c));
           }
       }
   }

}</lang>

Output:
      [1, 2, 3] -> e(1) + 2*e(2) + 3*e(3)
   [0, 1, 2, 3] -> e(2) + 2*e(3) + 3*e(4)
   [1, 0, 3, 4] -> e(1) + 3*e(3) + 4*e(4)
      [1, 2, 0] -> e(1) + 2*e(2)
      [0, 0, 0] -> 0
            [0] -> 0
      [1, 1, 1] -> e(1) + e(2) + e(3)
   [-1, -1, -1] -> -e(1) - e(2) - e(3)
[-1, -2, 0, -3] -> -e(1) - 2*e(2) - 3*e(4)
           [-1] -> -e(1)

C++

Translation of: D

<lang cpp>#include <iomanip>

  1. include <iostream>
  2. include <sstream>
  3. include <vector>

template<typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {

   auto it = v.cbegin();
   auto end = v.cend();
   os << '[';
   if (it != end) {
       os << *it;
       it = std::next(it);
   }
   while (it != end) {
       os << ", " << *it;
       it = std::next(it);
   }
   return os << ']';

}

std::ostream& operator<<(std::ostream& os, const std::string& s) {

   return os << s.c_str();

}

std::string linearCombo(const std::vector<int>& c) {

   std::stringstream ss;
   for (size_t i = 0; i < c.size(); i++) {
       int n = c[i];
       if (n < 0) {
           if (ss.tellp() == 0) {
               ss << '-';
           } else {
               ss << " - ";
           }
       } else if (n > 0) {
           if (ss.tellp() != 0) {
               ss << " + ";
           }
       } else {
           continue;
       }
       int av = abs(n);
       if (av != 1) {
           ss << av << '*';
       }
       ss << "e(" << i + 1 << ')';
   }
   if (ss.tellp() == 0) {
       return "0";
   }
   return ss.str();

}

int main() {

   using namespace std;
   vector<vector<int>> combos{
       {1, 2, 3},
       {0, 1, 2, 3},
       {1, 0, 3, 4},
       {1, 2, 0},
       {0, 0, 0},
       {0},
       {1, 1, 1},
       {-1, -1, -1},
       {-1, -2, 0, -3},
       {-1},
   };
   for (auto& c : combos) {
       stringstream ss;
       ss << c;
       cout << setw(15) << ss.str() << " -> ";
       cout << linearCombo(c) << '\n';
   }
   return 0;

}</lang>

Output:
      [1, 2, 3] -> e(1) + 2*e(2) + 3*e(3)
   [0, 1, 2, 3] -> e(2) + 2*e(3) + 3*e(4)
   [1, 0, 3, 4] -> e(1) + 3*e(3) + 4*e(4)
      [1, 2, 0] -> e(1) + 2*e(2)
      [0, 0, 0] -> 0
            [0] -> 0
      [1, 1, 1] -> e(1) + e(2) + e(3)
   [-1, -1, -1] -> -e(1) - e(2) - e(3)
[-1, -2, 0, -3] -> -e(1) - 2*e(2) - 3*e(4)
           [-1] -> -e(1)

D

Translation of: Kotlin

<lang D>import std.array; import std.conv; import std.format; import std.math; import std.stdio;

string linearCombo(int[] c) {

   auto sb = appender!string;
   foreach (i, n; c) {
       if (n==0) continue;
       string op;
       if (n < 0) {
           if (sb.data.empty) {
               op = "-";
           } else {
               op = " - ";
           }
       } else if (n > 0) {
           if (!sb.data.empty) {
               op = " + ";
           }
       }
       auto av = abs(n);
       string coeff;
       if (av != 1) {
           coeff = to!string(av) ~ "*";
       }
       sb.formattedWrite("%s%se(%d)", op, coeff, i+1);
   }
   if (sb.data.empty) {
       return "0";
   }
   return sb.data;

}

void main() {

   auto combos = [
       [1, 2, 3],
       [0, 1, 2, 3],
       [1, 0, 3, 4],
       [1, 2, 0],
       [0, 0, 0],
       [0],
       [1, 1, 1],
       [-1, -1, -1],
       [-1, -2, 0, -3],
       [-1],
   ];
   foreach (c; combos) {
       auto arr = c.format!"%s";
       writefln("%-15s  ->  %s", arr, linearCombo(c));
   }

}</lang>

Output:
[1, 2, 3]        ->  e(1) + 2*e(2) + 3*e(3)
[0, 1, 2, 3]     ->  e(2) + 2*e(3) + 3*e(4)
[1, 0, 3, 4]     ->  e(1) + 3*e(3) + 4*e(4)
[1, 2, 0]        ->  e(1) + 2*e(2)
[0, 0, 0]        ->  0
[0]              ->  0
[1, 1, 1]        ->  e(1) + e(2) + e(3)
[-1, -1, -1]     ->  -e(1) - e(2) - e(3)
[-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
[-1]             ->  -e(1)

EchoLisp

<lang scheme>

build an html string from list of coeffs

(define (linear->html coeffs)

   (define plus #f) 
   (or* 
   (for/fold (html "") ((a coeffs) (i (in-naturals 1)))
     (unless (zero? a)
		(set! plus (if plus "+" "")))
     (string-append html

(cond ((= a 1) (format "%a e%d " plus i)) ((= a -1) (format "- e%d " i)) ((> a 0) (format "%a %d*e%d " plus a i)) ((< a 0) (format "- %d*e%d " (abs a) i)) (else ""))))

    "0"))

(define linears '((1 2 3)

  (0 1 2 3)
  (1 0 3 4)
  (1 2 0)
  (0 0 0)
  (0)
  (1 1 1)
  (-1 -1 -1)
  (-1 -2 0 -3)
  (-1)))
  

(define (task linears)

   (html-print ;; send string to stdout
   (for/string ((linear linears))
     (format "%a -> %a 
" linear (linear->html linear)))))

</lang>

Output:

(1 2 3) -> e1 + 2*e2 + 3*e3
(0 1 2 3) -> e2 + 2*e3 + 3*e4
(1 0 3 4) -> e1 + 3*e3 + 4*e4
(1 2 0) -> e1 + 2*e2
(0 0 0) -> 0
(0) -> 0
(1 1 1) -> e1 + e2 + e3
(-1 -1 -1) -> - e1 - e2 - e3
(-1 -2 0 -3) -> - e1 - 2*e2 - 3*e4
(-1) -> - e1

Elixir

Works with: Elixir version 1.3

<lang elixir>defmodule Linear_combination do

 def display(coeff) do
   Enum.with_index(coeff)
   |> Enum.map_join(fn {n,i} ->
        {m,s} = if n<0, do: {-n,"-"}, else: {n,"+"}
        case {m,i} do
          {0,_} -> ""
          {1,i} -> "#{s}e(#{i+1})"
          {n,i} -> "#{s}#{n}*e(#{i+1})"
        end
      end)
   |> String.trim_leading("+")
   |> case do
        ""  -> IO.puts "0"
        str -> IO.puts str
      end
 end

end

coeffs =

 [ [1, 2, 3],
   [0, 1, 2, 3],
   [1, 0, 3, 4],
   [1, 2, 0],
   [0, 0, 0],
   [0],
   [1, 1, 1],
   [-1, -1, -1],
   [-1, -2, 0, -3],
   [-1]
 ]

Enum.each(coeffs, &Linear_combination.display(&1))</lang>

Output:
e(1)+2*e(2)+3*e(3)
e(2)+2*e(3)+3*e(4)
e(1)+3*e(3)+4*e(4)
e(1)+2*e(2)
0
0
e(1)+e(2)+e(3)
-e(1)-e(2)-e(3)
-e(1)-2*e(2)-3*e(4)
-e(1)

F#

The function

<lang fsharp> // Display a linear combination. Nigel Galloway: March 28th., 2018 let fN g =

 let rec fG n g=match g with
                |0::g    ->                        fG (n+1) g
                |1::g    -> printf "+e(%d)" n;     fG (n+1) g
                |(-1)::g -> printf "-e(%d)" n;     fG (n+1) g
                |i::g    -> printf "%+de(%d)" i n; fG (n+1) g
                |_       -> printfn ""
 let rec fN n g=match g with
                |0::g    ->                        fN (n+1) g
                |1::g    -> printf "e(%d)" n;      fG (n+1) g
                |(-1)::g -> printf "-e(%d)" n;     fG (n+1) g
                |i::g    -> printf "%de(%d)" i n;  fG (n+1) g
                |_       -> printfn "0"
 fN 1 g

</lang>

The Task

<lang fsharp> fN [1;2;3] </lang>

Output:
e(1)+2e(2)+3e(3)

<lang fsharp> fN [0;1;2;3] </lang>

Output:
e(2)+2e(3)+3e(4)

<lang fsharp> fN[1;0;3;4] </lang>

Output:
e(1)+3e(3)+4e(4)

<lang fsharp> fN[1;2;0] </lang>

Output:
e(1)+2e(2)

<lang fsharp> fN[0;0;0] </lang>

Output:
0

<lang fsharp> fN[0] </lang>

Output:
0

<lang fsharp> fN[1;1;1] </lang>

Output:
e(1)+e(2)+e(3)

<lang fsharp> fN[-1;-1;-1] </lang>

Output:
-e(1)-e(2)-e(3)

<lang fsharp> fN[-1;-2;0;-3] </lang>

Output:
-e(1)-2e(2)-3e(4)

<lang fsharp> fN[1] </lang>

Output:
e(1)

Factor

<lang factor>USING: formatting kernel match math pair-rocket regexp sequences ;

MATCH-VARS: ?a ?b ;

choose-term ( coeff i -- str )
   1 + { } 2sequence {
       {  0  _ } => [       ""                 ]
       {  1 ?a } => [ ?a    "e(%d)"    sprintf ]
       { -1 ?a } => [ ?a    "-e(%d)"   sprintf ]
       { ?a ?b } => [ ?a ?b "%d*e(%d)" sprintf ]
   } match-cond ;
   
linear-combo ( seq -- str )
   [ choose-term ] map-index harvest " + " join
   R/ \+ -/ "- " re-replace [ "0" ] when-empty ;
   

{ { 1 2 3 } { 0 1 2 3 } { 1 0 3 4 } { 1 2 0 } { 0 0 0 } { 0 }

 { 1 1 1 } { -1 -1 -1 } { -1 -2 0 -3 } { -1 } }

[ dup linear-combo "%-14u -> %s\n" printf ] each</lang>

Output:
{ 1 2 3 }       ->  e(1) + 2*e(2) + 3*e(3)
{ 0 1 2 3 }     ->  e(2) + 2*e(3) + 3*e(4)
{ 1 0 3 4 }     ->  e(1) + 3*e(3) + 4*e(4)
{ 1 2 0 }       ->  e(1) + 2*e(2)
{ 0 0 0 }       ->  0
{ 0 }           ->  0
{ 1 1 1 }       ->  e(1) + e(2) + e(3)
{ -1 -1 -1 }    ->  -e(1) - e(2) - e(3)
{ -1 -2 0 -3 }  ->  -e(1) - 2*e(2) - 3*e(4)
{ -1 }          ->  -e(1)

Go

Translation of: Kotlin

<lang go>package main

import (

   "fmt"
   "strings"

)

func linearCombo(c []int) string {

   var sb strings.Builder
   for i, n := range c {
       if n == 0 {
           continue
       }
       var op string
       switch {
       case n < 0 && sb.Len() == 0:
           op = "-"
       case n < 0:
           op = " - "
       case n > 0 && sb.Len() == 0:
           op = ""
       default:
           op = " + "
       }
       av := n
       if av < 0 {
           av = -av
       }
       coeff := fmt.Sprintf("%d*", av)
       if av == 1 {
           coeff = ""
       }
       sb.WriteString(fmt.Sprintf("%s%se(%d)", op, coeff, i+1))
   }
   if sb.Len() == 0 {
       return "0"
   } else {
       return sb.String()
   }

}

func main() {

   combos := [][]int{
       {1, 2, 3},
       {0, 1, 2, 3},
       {1, 0, 3, 4},
       {1, 2, 0},
       {0, 0, 0},
       {0},
       {1, 1, 1},
       {-1, -1, -1},
       {-1, -2, 0, -3},
       {-1},
   }
   for _, c := range combos {
       t := strings.Replace(fmt.Sprint(c), " ", ", ", -1)
       fmt.Printf("%-15s  ->  %s\n", t, linearCombo(c))
   }

}</lang>

Output:
[1, 2, 3]        ->  e(1) + 2*e(2) + 3*e(3)
[0, 1, 2, 3]     ->  e(2) + 2*e(3) + 3*e(4)
[1, 0, 3, 4]     ->  e(1) + 3*e(3) + 4*e(4)
[1, 2, 0]        ->  e(1) + 2*e(2)
[0, 0, 0]        ->  0
[0]              ->  0
[1, 1, 1]        ->  e(1) + e(2) + e(3)
[-1, -1, -1]     ->  -e(1) - e(2) - e(3)
[-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
[-1]             ->  -e(1)

Groovy

Translation of: Java

<lang groovy>class LinearCombination {

   private static String linearCombo(int[] c) {
       StringBuilder sb = new StringBuilder()
       for (int i = 0; i < c.length; ++i) {
           if (c[i] == 0) continue
           String op
           if (c[i] < 0 && sb.length() == 0) {
               op = "-"
           } else if (c[i] < 0) {
               op = " - "
           } else if (c[i] > 0 && sb.length() == 0) {
               op = ""
           } else {
               op = " + "
           }
           int av = Math.abs(c[i])
           String coeff = av == 1 ? "" : "" + av + "*"
           sb.append(op).append(coeff).append("e(").append(i + 1).append(')')
       }
       if (sb.length() == 0) {
           return "0"
       }
       return sb.toString()
   }
   static void main(String[] args) {
       int[][] combos = [
               [1, 2, 3],
               [0, 1, 2, 3],
               [1, 0, 3, 4],
               [1, 2, 0],
               [0, 0, 0],
               [0],
               [1, 1, 1],
               [-1, -1, -1],
               [-1, -2, 0, -3],
               [-1]
       ]
       for (int[] c : combos) {
           printf("%-15s  ->  %s\n", Arrays.toString(c), linearCombo(c))
       }
   }

}</lang>

Output:
[1, 2, 3]        ->  e(1) + 2*e(2) + 3*e(3)
[0, 1, 2, 3]     ->  e(2) + 2*e(3) + 3*e(4)
[1, 0, 3, 4]     ->  e(1) + 3*e(3) + 4*e(4)
[1, 2, 0]        ->  e(1) + 2*e(2)
[0, 0, 0]        ->  0
[0]              ->  0
[1, 1, 1]        ->  e(1) + e(2) + e(3)
[-1, -1, -1]     ->  -e(1) - e(2) - e(3)
[-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
[-1]             ->  -e(1)

J

Implementation:

<lang J>fourbanger=:3 :0

 e=. ('e(',')',~])@":&.> 1+i.#y
 firstpos=. 0< {.y-.0
 if. */0=y do. '0' else. firstpos}.;y gluedto e end.

)

gluedto=:4 :0 each

 pfx=. '+-' {~ x<0
 select. |x
   case. 0 do. 
   case. 1 do. pfx,y
   case.   do. pfx,(":|x),'*',y
 end.

)</lang>

Example use:

<lang J> fourbanger 1 2 3 e(1)+2*e(2)+3*e(3)

  fourbanger 0 1 2 3

e(2)+2*e(3)+3*e(4)

  fourbanger 1 0 3 4

e(1)+3*e(3)+4*e(4)

  fourbanger 0 0 0

0

  fourbanger 0

0

  fourbanger 1 1 1

e(1)+e(2)+e(3)

  fourbanger _1 _1 _1

-e(1)-e(2)-e(3)

  fourbanger _1 _2 0 _3

-e(1)-2*e(2)-3*e(4)

  fourbanger _1

-e(1)</lang>

Java

Translation of: Kotlin

<lang Java>import java.util.Arrays;

public class LinearCombination {

   private static String linearCombo(int[] c) {
       StringBuilder sb = new StringBuilder();
       for (int i = 0; i < c.length; ++i) {
           if (c[i] == 0) continue;
           String op;
           if (c[i] < 0 && sb.length() == 0) {
               op = "-";
           } else if (c[i] < 0) {
               op = " - ";
           } else if (c[i] > 0 && sb.length() == 0) {
               op = "";
           } else {
               op = " + ";
           }
           int av = Math.abs(c[i]);
           String coeff = av == 1 ? "" : "" + av + "*";
           sb.append(op).append(coeff).append("e(").append(i + 1).append(')');
       }
       if (sb.length() == 0) {
           return "0";
       }
       return sb.toString();
   }
   public static void main(String[] args) {
       int[][] combos = new int[][]{
           new int[]{1, 2, 3},
           new int[]{0, 1, 2, 3},
           new int[]{1, 0, 3, 4},
           new int[]{1, 2, 0},
           new int[]{0, 0, 0},
           new int[]{0},
           new int[]{1, 1, 1},
           new int[]{-1, -1, -1},
           new int[]{-1, -2, 0, -3},
           new int[]{-1},
       };
       for (int[] c : combos) {
           System.out.printf("%-15s  ->  %s\n", Arrays.toString(c), linearCombo(c));
       }
   }

}</lang>

Output:
[1, 2, 3]        ->  e(1) + 2*e(2) + 3*e(3)
[0, 1, 2, 3]     ->  e(2) + 2*e(3) + 3*e(4)
[1, 0, 3, 4]     ->  e(1) + 3*e(3) + 4*e(4)
[1, 2, 0]        ->  e(1) + 2*e(2)
[0, 0, 0]        ->  0
[0]              ->  0
[1, 1, 1]        ->  e(1) + e(2) + e(3)
[-1, -1, -1]     ->  -e(1) - e(2) - e(3)
[-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
[-1]             ->  -e(1)

Julia

<lang julia># v0.6

linearcombination(coef::Array) = join(collect("$c * e($i)" for (i, c) in enumerate(coef) if c != 0), " + ")

for c in [[1, 2, 3], [0, 1, 2, 3], [1, 0, 3, 4], [1, 2, 0], [0, 0, 0], [0], [1, 1, 1],

   [-1, -1, -1], [-1, -2, 0, -3], [-1]]
   @printf("%20s -> %s\n", c, linearcombination(c))

end</lang>

Output:
           [1, 2, 3] -> 1 * e(1) + 2 * e(2) + 3 * e(3)
        [0, 1, 2, 3] -> 1 * e(2) + 2 * e(3) + 3 * e(4)
        [1, 0, 3, 4] -> 1 * e(1) + 3 * e(3) + 4 * e(4)
           [1, 2, 0] -> 1 * e(1) + 2 * e(2)
           [0, 0, 0] -> 
                 [0] -> 
           [1, 1, 1] -> 1 * e(1) + 1 * e(2) + 1 * e(3)
        [-1, -1, -1] -> -1 * e(1) + -1 * e(2) + -1 * e(3)
     [-1, -2, 0, -3] -> -1 * e(1) + -2 * e(2) + -3 * e(4)
                [-1] -> -1 * e(1)

Kotlin

<lang scala>// version 1.1.2

fun linearCombo(c: IntArray): String {

   val sb = StringBuilder()
   for ((i, n) in c.withIndex()) {
       if (n == 0) continue
       val op = when {
           n < 0 && sb.isEmpty() -> "-"
           n < 0                 -> " - "
           n > 0 && sb.isEmpty() -> ""
           else                  -> " + "
       }
       val av = Math.abs(n)
       val coeff = if (av == 1) "" else "$av*"
       sb.append("$op${coeff}e(${i + 1})")
   }
   return if(sb.isEmpty()) "0" else sb.toString()

}

fun main(args: Array<String>) {

   val combos = arrayOf(
       intArrayOf(1, 2, 3),
       intArrayOf(0, 1, 2, 3),
       intArrayOf(1, 0, 3, 4),
       intArrayOf(1, 2, 0),
       intArrayOf(0, 0, 0),
       intArrayOf(0),
       intArrayOf(1, 1, 1),
       intArrayOf(-1, -1, -1),
       intArrayOf(-1, -2, 0, -3),
       intArrayOf(-1)
   )
   for (c in combos) {
       println("${c.contentToString().padEnd(15)}  ->  ${linearCombo(c)}")
   }

}</lang>

Output:
[1, 2, 3]        ->  e(1) + 2*e(2) + 3*e(3)
[0, 1, 2, 3]     ->  e(2) + 2*e(3) + 3*e(4)
[1, 0, 3, 4]     ->  e(1) + 3*e(3) + 4*e(4)
[1, 2, 0]        ->  e(1) + 2*e(2)
[0, 0, 0]        ->  0
[0]              ->  0
[1, 1, 1]        ->  e(1) + e(2) + e(3)
[-1, -1, -1]     ->  -e(1) - e(2) - e(3)
[-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
[-1]             ->  -e(1)

Lambdatalk

<lang scheme>

{def linearcomb

{def linearcomb.r
 {lambda {:a :n :i}
  {if {= :i :n}
   then 
   else {let { {:e e({+ :i 1})}
               {:v {abs {A.get :i :a}}}
               {:s {if {< {A.get :i :a} 0} then - else +}}
             } {if {= :v 0} then  else
               {if {= :v 1} then :s :e else :s :v*:e}}}
        {linearcomb.r :a :n {+ :i 1}} }}}
{lambda {:a}
 {S.replace _LAMB_[^\s]+ by 0 in
  {let { {:r {linearcomb.r {A.new :a} {S.length :a} 0}}
       } {if {W.equal? {S.first :r} +} then {S.rest :r} else :r} }}}}

-> linearcomb

{linearcomb 1 2 3} -> e(1) + 2*e(2) + 3*e(3) {linearcomb -1 -2 0 -3} -> - e(1) - 2*e(2) - 3*e(4) {linearcomb 0 1 2 3} -> e(2) + 2*e(3) + 3*e(4) {linearcomb 1 0 3 4} -> e(1) + 3*e(3) + 4*e(4) {linearcomb 1 2 0} -> e(1) + 2*e(2) {linearcomb 0 0 0} -> 0 {linearcomb 0} -> 0 {linearcomb 1 1 1} -> e(1) + e(2) + e(3) {linearcomb -1 -1 -1} -> - e(1) - e(2) - e(3) {linearcomb -1} -> - e(1)

</lang>

Lua

Translation of: C#

<lang lua>function t2s(t)

   local s = "["
   for i,v in pairs(t) do
       if i > 1 then
           s = s .. ", " .. v
       else
           s = s .. v
       end
   end
   return s .. "]"

end

function linearCombo(c)

   local sb = ""
   for i,n in pairs(c) do
       local skip = false
       if n < 0 then
           if sb:len() == 0 then
               sb = sb .. "-"
           else
               sb = sb .. " - "
           end
       elseif n > 0 then
           if sb:len() ~= 0 then
               sb = sb .. " + "
           end
       else
           skip = true
       end
       if not skip then
           local av = math.abs(n)
           if av ~= 1 then
               sb = sb .. av .. "*"
           end
           sb = sb .. "e(" .. i .. ")"
       end
   end
   if sb:len() == 0 then
       sb = "0"
   end
   return sb

end

function main()

   local combos = {
       {  1,  2,  3},
       {  0,  1,  2,  3 },
       {  1,  0,  3,  4 },
       {  1,  2,  0 },
       {  0,  0,  0 },
       {  0 },
       {  1,  1,  1 },
       { -1, -1, -1 },
       { -1, -2, 0, -3 },
       { -1 }
   }
   for i,c in pairs(combos) do
       local arr = t2s(c)
       print(string.format("%15s -> %s", arr, linearCombo(c)))
   end

end

main()</lang>

Output:
      [1, 2, 3] -> e(1) + 2*e(2) + 3*e(3)
   [0, 1, 2, 3] -> e(2) + 2*e(3) + 3*e(4)
   [1, 0, 3, 4] -> e(1) + 3*e(3) + 4*e(4)
      [1, 2, 0] -> e(1) + 2*e(2)
      [0, 0, 0] -> 0
            [0] -> 0
      [1, 1, 1] -> e(1) + e(2) + e(3)
   [-1, -1, -1] -> -e(1) - e(2) - e(3)
[-1, -2, 0, -3] -> -e(1) - 2*e(2) - 3*e(4)
           [-1] -> -e(1)

Modula-2

<lang modula2>MODULE Linear; FROM FormatString IMPORT FormatString; FROM Terminal IMPORT WriteString,WriteLn,ReadChar;

PROCEDURE WriteInt(n : INTEGER); VAR buf : ARRAY[0..15] OF CHAR; BEGIN

   FormatString("%i", buf, n);
   WriteString(buf)

END WriteInt;

PROCEDURE WriteLinear(c : ARRAY OF INTEGER); VAR

   buf : ARRAY[0..15] OF CHAR;
   i,j : CARDINAL;
   b : BOOLEAN;

BEGIN

   b := TRUE;
   j := 0;
   FOR i:=0 TO HIGH(c) DO
       IF c[i]=0 THEN CONTINUE END;
       IF c[i]<0 THEN
           IF b THEN WriteString("-")
           ELSE      WriteString(" - ") END;
       ELSIF c[i]>0 THEN
           IF NOT b THEN WriteString(" + ") END;
       END;
       IF c[i] > 1 THEN
           WriteInt(c[i]);
           WriteString("*")
       ELSIF c[i] < -1 THEN
           WriteInt(-c[i]);
           WriteString("*")
       END;
       FormatString("e(%i)", buf, i+1);
       WriteString(buf);
       b := FALSE;
       INC(j)
   END;
   IF j=0 THEN WriteString("0") END;
   WriteLn

END WriteLinear;

TYPE

   Array1 = ARRAY[0..0] OF INTEGER;
   Array3 = ARRAY[0..2] OF INTEGER;
   Array4 = ARRAY[0..3] OF INTEGER;

BEGIN

   WriteLinear(Array3{1,2,3});
   WriteLinear(Array4{0,1,2,3});
   WriteLinear(Array4{1,0,3,4});
   WriteLinear(Array3{1,2,0});
   WriteLinear(Array3{0,0,0});
   WriteLinear(Array1{0});
   WriteLinear(Array3{1,1,1});
   WriteLinear(Array3{-1,-1,-1});
   WriteLinear(Array4{-1,-2,0,-3});
   WriteLinear(Array1{-1});
   ReadChar

END Linear.</lang>

Perl

<lang perl>use strict; use warnings; use feature 'say';

sub linear_combination {

   my(@coef) = @$_;
   my $e = ;
   for my $c (1..+@coef) { $e .= "$coef[$c-1]*e($c) + " if $coef[$c-1] }
   $e =~ s/ \+ $//;
   $e =~ s/1\*//g;
   $e =~ s/\+ -/- /g;
   $e or 0;

}

say linear_combination($_) for

 [1, 2, 3], [0, 1, 2, 3], [1, 0, 3, 4], [1, 2, 0], [0, 0, 0], [0], [1, 1, 1], [-1, -1, -1], [-1, -2, 0, -3], [-1 ]</lang>
Output:
e(1) + 2*e(2) + 3*e(3)
e(2) + 2*e(3) + 3*e(4)
e(1) + 3*e(3) + 4*e(4)
e(1) + 2*e(2)
0
0
e(1) + e(2) + e(3)
-e(1) - e(2) - e(3)
-e(1) - 2*e(2) - 3*e(4)
-e(1)

Phix

Translation of: Tcl

<lang Phix>function linear_combination(sequence f)

   string res = ""
   for e=1 to length(f) do
       integer fe = f[e]
       if fe!=0 then
           if fe=1 then
               if length(res) then res &= "+" end if
           elsif fe=-1 then
               res &= "-"
           elsif fe>0 and length(res) then
               res &= sprintf("+%d*",fe)
           else
               res &= sprintf("%d*",fe)
           end if
           res &= sprintf("e(%d)",e)
       end if
   end for
   if res="" then res = "0" end if
   return res

end function

constant tests = {{1,2,3},

                 {0,1,2,3},
                 {1,0,3,4},
                 {1,2,0},
                 {0,0,0},
                 {0},
                 {1,1,1},
                 {-1,-1,-1},
                 {-1,-2,0,-3},
                 {-1}}

for i=1 to length(tests) do

   sequence ti = tests[i]
   printf(1,"%12s -> %s\n",{sprint(ti), linear_combination(ti)})

end for</lang>

Output:
     {1,2,3} -> e(1)+2*e(2)+3*e(3)
   {0,1,2,3} -> e(2)+2*e(3)+3*e(4)
   {1,0,3,4} -> e(1)+3*e(3)+4*e(4)
     {1,2,0} -> e(1)+2*e(2)
     {0,0,0} -> 0
         {0} -> 0
     {1,1,1} -> e(1)+e(2)+e(3)
  {-1,-1,-1} -> -e(1)-e(2)-e(3)
{-1,-2,0,-3} -> -e(1)-2*e(2)-3*e(4)
        {-1} -> -e(1)

PureBasic

<lang PureBasic>; Process and output values. Procedure WriteLinear(Array c.i(1))

 Define buf$,
        i.i, j.i, b,i
 
 b = #True
 j = 0
 
 For i = 0 To ArraySize(c(), 1) 
   If c(i) = 0 : Continue : EndIf
   
   If c(i) < 0
     If b : Print("-") : Else : Print(" - ") : EndIf
   ElseIf c(i) > 0
     If Not b : Print(" + ") : EndIf
   EndIf
   
   If c(i) > 1
     Print(Str(c(i))+"*")
   ElseIf c(i) < -1
     Print(Str(-c(i))+"*")
   EndIf
   
   Print("e("+Str(i+1)+")")
   
   b = #False
   j+1
 Next
 
 If j = 0 : Print("0") : EndIf
 PrintN("")

EndProcedure


Macro VectorHdl(Adr_Start, Adr_Stop)

 ; 1. Output of the input values  
 Define buf$ = "[", *adr_ptr
 For *adr_ptr = Adr_Start To Adr_Stop - SizeOf(Integer) Step SizeOf(Integer)
   buf$ + Str(PeekI(*adr_ptr))
   If *adr_ptr >= Adr_Stop - SizeOf(Integer)
     buf$ + "]  ->  "
   Else
     buf$ + ", "
   EndIf    
 Next
 buf$ =  RSet(buf$, 25)
 Print(buf$)  
 
 ; 2. Reserve memory, pass and process values.
 Dim a.i((Adr_Stop - Adr_Start) / SizeOf(Integer) -1)
 CopyMemory(Adr_Start, @a(0), Adr_Stop - Adr_Start)
 WriteLinear(a())

EndMacro


If OpenConsole("")

 ; Pass memory addresses of the data.
 VectorHdl(?V1, ?_V1)
 VectorHdl(?V2, ?_V2)
 VectorHdl(?V3, ?_V3)
 VectorHdl(?V4, ?_V4)
 VectorHdl(?V5, ?_V5)
 VectorHdl(?V6, ?_V6)
 VectorHdl(?V7, ?_V7)
 VectorHdl(?V8, ?_V8)
 VectorHdl(?V9, ?_V9)
 VectorHdl(?V10, ?_V10)    
 
 Input()

EndIf

End 0


DataSection

 V1:
 Data.i 1,2,3
 _V1:
 V2:
 Data.i 0,1,2,3
 _V2:
 V3:
 Data.i 1,0,3,4
 _V3:
 V4:
 Data.i 1,2,0
 _V4:
 V5:
 Data.i 0,0,0
 _V5:
 V6:
 Data.i 0
 _V6:
 V7:
 Data.i 1,1,1
 _V7:
 V8:
 Data.i -1,-1,-1
 _V8:
 V9:
 Data.i -1,-2,0,-3
 _V9:
 V10:
 Data.i -1
 _V10:  

EndDataSection</lang>

Output:
          [1, 2, 3]  ->  e(1) + 2*e(2) + 3*e(3)
       [0, 1, 2, 3]  ->  e(2) + 2*e(3) + 3*e(4)
       [1, 0, 3, 4]  ->  e(1) + 3*e(3) + 4*e(4)
          [1, 2, 0]  ->  e(1) + 2*e(2)
          [0, 0, 0]  ->  0
                [0]  ->  0
          [1, 1, 1]  ->  e(1) + e(2) + e(3)
       [-1, -1, -1]  ->  -e(1) - e(2) - e(3)
    [-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
               [-1]  ->  -e(1)

Python

<lang python> def linear(x):

   return ' + '.join(['{}e({})'.format('-' if v == -1 else  if v == 1 else str(v) + '*', i + 1)
       for i, v in enumerate(x) if v] or ['0']).replace(' + -', ' - ')

list(map(lambda x: print(linear(x)), [[1, 2, 3], [0, 1, 2, 3], [1, 0, 3, 4], [1, 2, 0],

       [0, 0, 0], [0], [1, 1, 1], [-1, -1, -1], [-1, -2, 0, 3], [-1]]))

</lang>

Output:
e(1) + 2*e(2) + 3*e(3)
e(2) + 2*e(3) + 3*e(4)
e(1) + 3*e(3) + 4*e(4)
e(1) + 2*e(2)
0
0
e(1) + e(2) + e(3)
-e(1) - e(2) - e(3)
-e(1) - 2*e(2) + 3*e(4)
-e(1)

Racket

<lang racket>#lang racket/base (require racket/match racket/string)

(define (linear-combination->string es)

 (let inr ((es es) (i 1) (rv ""))
   (match* (es rv)
     [((list) "") "0"]
     [((list) rv) rv]
     [((list (? zero?) t ...) rv)
      (inr t (add1 i) rv)]
     [((list n t ...) rv)
      (define ±n
        (match* (n rv)
          ;; zero is handled above
          [(1 "") ""]
          [(1 _) "+"]
          [(-1 _) "-"]
          [((? positive? n) (not "")) (format "+~a*" n)]
          [(n _) (format "~a*" n)]))
      (inr t (add1 i) (string-append rv ±n "e("(number->string i)")"))])))

(for-each

(compose displayln linear-combination->string)
'((1 2 3)
  (0 1 2 3)
  (1 0 3 4)
  (1 2 0)
  (0 0 0)
  (0)
  (1 1 1)
  (-1 -1 -1)
  (-1 -2 0 -3)
  (-1)))

</lang>

Output:
e(1)+2*e(2)+3*e(3)
e(2)+2*e(3)+3*e(4)
e(1)+3*e(3)+4*e(4)
e(1)+2*e(2)
0
0
e(1)+e(2)+e(3)
-e(1)-e(2)-e(3)
-e(1)-2*e(2)-3*e(4)
-e(1)

Raku

(formerly Perl 6) <lang perl6>sub linear-combination(@coeff) {

   (@coeff Z=> map { "e($_)" }, 1 .. *)
   .grep(+*.key)
   .map({ .key ~ '*' ~ .value })
   .join(' + ')
   .subst('+ -', '- ', :g)
   .subst(/<|w>1\*/, , :g)
       || '0'

}

say linear-combination($_) for [1, 2, 3], [0, 1, 2, 3], [1, 0, 3, 4], [1, 2, 0], [0, 0, 0], [0], [1, 1, 1], [-1, -1, -1], [-1, -2, 0, -3], [-1 ]

</lang>
Output:
e(1) + 2*e(2) + 3*e(3)
e(2) + 2*e(3) + 3*e(4)
e(1) + 3*e(3) + 4*e(4)
e(1) + 2*e(2)
0
0
e(1) + e(2) + e(3)
-e(1) - e(2) - e(3)
-e(1) - 2*e(2) - 3*e(4)
-e(1)

REXX

<lang rexx>/*REXX program displays a finite liner combination in an infinite vector basis. */ @.= .; @.1 = ' 1, 2, 3 ' /*define a specific test case for build*/

                @.2  =    '  0,  1,  2,  3 '    /*   "   "     "      "    "   "    "  */
                @.3  =    '  1,  0,  3,  4 '    /*   "   "     "      "    "   "    "  */
                @.4  =    '  1,  2,  0     '    /*   "   "     "      "    "   "    "  */
                @.5  =    '  0,  0,  0     '    /*   "   "     "      "    "   "    "  */
                @.6  =       0                  /*   "   "     "      "    "   "    "  */
                @.7  =    '  1,  1,  1     '    /*   "   "     "      "    "   "    "  */
                @.8  =    ' -1, -1, -1     '    /*   "   "     "      "    "   "    "  */
                @.9  =    ' -1, -2,  0, -3 '    /*   "   "     "      "    "   "    "  */
                @.10 =      -1                  /*   "   "     "      "    "   "    "  */
 do j=1  while  @.j\==.;        n= 0            /*process each vector; zero element cnt*/
 y= space( translate(@.j, ,',') )               /*elide commas and superfluous blanks. */
 $=                                             /*nullify  output  (liner combination).*/
      do k=1  for words(y);     #= word(y, k)   /* ◄───── process each of the elements.*/
      if #=0  then iterate;     a= abs(# / 1)   /*if the value is zero, then ignore it.*/
      if #<0  then s= '- '                      /*define the sign:   minus (-).        */
              else s= '+ '                      /*   "    "    "     plus  (+).        */
      n= n + 1                                  /*bump the number of elements in vector*/
      if n==1  then s= strip(s)                 /*if the 1st element used, remove blank*/
      if a\==1    then s= s  ||  a'*'  /*if multiplier is unity, then ignore #*/
      $= $  s'e('k")"                           /*construct a liner combination element*/
      end   /*k*/
 $= strip( strip($), 'L', "+")                  /*strip leading plus sign (1st element)*/
 if $==  then $= 0                            /*handle special case of no elements.  */
 say right( space(@.j), 20)  ' ──► '   strip($) /*align the output for presentation.   */
 end       /*j*/                                /*stick a fork in it,  we're all done. */</lang>
output   when using the default inputs:
             1, 2, 3  ──►  e(1) + 2*e(2) + 3*e(3)
          0, 1, 2, 3  ──►  e(2) + 2*e(3) + 3*e(4)
          1, 0, 3, 4  ──►  e(1) + 3*e(3) + 4*e(4)
             1, 2, 0  ──►  e(1) + 2*e(2)
             0, 0, 0  ──►  0
                   0  ──►  0
             1, 1, 1  ──►  e(1) + e(2) + e(3)
          -1, -1, -1  ──►  -e(1) - e(2) - e(3)
       -1, -2, 0, -3  ──►  -e(1) - 2*e(2) - 3*e(4)
                  -1  ──►  -e(1)

Ring

<lang ring>

  1. Project : Display a linear combination

scalars = [[1, 2, 3], [0, 1, 2, 3], [1, 0, 3, 4], [1, 2, 0], [0, 0, 0], [0], [1, 1, 1], [-1, -1, -1], [-1, -2, 0, -3], [-1]] for n=1 to len(scalars)

   str = ""
   for m=1 to len(scalars[n])
       scalar = scalars[n] [m]
       if scalar != "0"
          if scalar = 1
             str = str + "+e" + m
          elseif  scalar = -1
             str = str + "" + "-e" + m
          else
             if scalar > 0
                str = str + char(43) + scalar + "*e" + m
             else
                str = str + "" + scalar + "*e" + m
             ok
          ok
       ok   
   next
   if str = ""
      str = "0"
   ok
   if left(str, 1) = "+"
      str = right(str, len(str)-1)
   ok
   see str + nl

next </lang> Output:

e1+2*e2+3*e3
e2+2*e3+3*e4
e1+3*e3+4*e4
e1+2*e2
0
0
e1+e2+e3
-e1-e2-e3
-e1-2*e2-3*e4
-e1

Ruby

Translation of: D

<lang ruby>def linearCombo(c)

   sb = ""
   c.each_with_index { |n, i|
       if n == 0 then
           next
       end
       if n < 0 then
           if sb.length == 0 then
               op = "-"
           else
               op = " - "
           end
       elsif n > 0 then
           if sb.length > 0 then
               op = " + "
           else
               op = ""
           end
       else
           op = ""
       end
       av = n.abs()
       if av != 1 then
           coeff = "%d*" % [av]
       else
           coeff = ""
       end
       sb = sb + "%s%se(%d)" % [op, coeff, i + 1]
   }
   if sb.length == 0 then
       return "0"
   end
   return sb

end

def main

   combos = [
       [1, 2, 3],
       [0, 1, 2, 3],
       [1, 0, 3, 4],
       [1, 2, 0],
       [0, 0, 0],
       [0],
       [1, 1, 1],
       [-1, -1, -1],
       [-1, -2, 0, -3],
       [-1],
   ]
   for c in combos do
       print "%-15s  ->  %s\n" % [c, linearCombo(c)]
   end

end

main()</lang>

Output:
[1, 2, 3]        ->  e(1) + 2*e(2) + 3*e(3)
[0, 1, 2, 3]     ->  e(2) + 2*e(3) + 3*e(4)
[1, 0, 3, 4]     ->  e(1) + 3*e(3) + 4*e(4)
[1, 2, 0]        ->  e(1) + 2*e(2)
[0, 0, 0]        ->  0
[0]              ->  0
[1, 1, 1]        ->  e(1) + e(2) + e(3)
[-1, -1, -1]     ->  -e(1) - e(2) - e(3)
[-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
[-1]             ->  -e(1)

Scala

<lang Scala>object LinearCombination extends App {

   val combos = Seq(Seq(1, 2, 3), Seq(0, 1, 2, 3),
     Seq(1, 0, 3, 4), Seq(1, 2, 0), Seq(0, 0, 0), Seq(0),
     Seq(1, 1, 1), Seq(-1, -1, -1), Seq(-1, -2, 0, -3), Seq(-1))
 private def linearCombo(c: Seq[Int]): String = {
   val sb = new StringBuilder
   for {i <- c.indices
        term = c(i)
        if term != 0} {
     val av = math.abs(term)
     def op = if (term < 0 && sb.isEmpty) "-"
     else if (term < 0) " - "
     else if (term > 0 && sb.isEmpty) "" else " + "
     sb.append(op).append(if (av == 1) "" else s"$av*").append("e(").append(i + 1).append(')')
   }
   if (sb.isEmpty) "0" else sb.toString
 }
   for (c <- combos) {
     println(f"${c.mkString("[", ", ", "]")}%-15s  ->  ${linearCombo(c)}%s")
   }

}</lang>

Sidef

Translation of: Tcl

<lang ruby>func linear_combination(coeffs) {

   var res = ""
   for e,f in (coeffs.kv) {
       given(f) {
           when (1) {
               res += "+e(#{e+1})"
           }
           when (-1) {
               res += "-e(#{e+1})"
           }
           case (.> 0) {
               res += "+#{f}*e(#{e+1})"
           }
           case (.< 0) {
               res += "#{f}*e(#{e+1})"
           }
       }
   }
   res -= /^\+/
   res || 0

}

var tests = [

   %n{1 2 3},
   %n{0 1 2 3},
   %n{1 0 3 4},
   %n{1 2 0},
   %n{0 0 0},
   %n{0},
   %n{1 1 1},
   %n{-1 -1 -1},
   %n{-1 -2 0 -3},
   %n{-1},

]

tests.each { |t|

   printf("%10s -> %-10s\n", t.join(' '), linear_combination(t))

}</lang>

Output:
     1 2 3 -> e(1)+2*e(2)+3*e(3)
   0 1 2 3 -> e(2)+2*e(3)+3*e(4)
   1 0 3 4 -> e(1)+3*e(3)+4*e(4)
     1 2 0 -> e(1)+2*e(2)
     0 0 0 -> 0         
         0 -> 0         
     1 1 1 -> e(1)+e(2)+e(3)
  -1 -1 -1 -> -e(1)-e(2)-e(3)
-1 -2 0 -3 -> -e(1)-2*e(2)-3*e(4)
        -1 -> -e(1)     

Tcl

This solution strives for legibility rather than golf.

<lang Tcl>proc lincom {factors} {

   set exp 0
   set res ""
   foreach f $factors {
       incr exp
       if {$f == 0} {
           continue
       } elseif {$f == 1} {
           append res "+e($exp)"
       } elseif {$f == -1} {
           append res "-e($exp)"
       } elseif {$f > 0} {
           append res "+$f*e($exp)"
       } else {
           append res "$f*e($exp)"
       }
   }
   if {$res eq ""} {set res 0}
   regsub {^\+} $res {} res
   return $res

}

foreach test {

   {1 2 3}
   {0 1 2 3}
   {1 0 3 4}
   {1 2 0}
   {0 0 0}
   {0}
   {1 1 1}
   {-1 -1 -1}
   {-1 -2 0 -3}
   {-1}

} {

   puts [format "%10s -> %-10s" $test [lincom $test]]

}</lang>

Output:
     1 2 3 -> e(1)+2*e(2)+3*e(3)
   0 1 2 3 -> e(2)+2*e(3)+3*e(4)
   1 0 3 4 -> e(1)+3*e(3)+4*e(4)
     1 2 0 -> e(1)+2*e(2)
     0 0 0 -> 0         
         0 -> 0         
     1 1 1 -> e(1)+e(2)+e(3)
  -1 -1 -1 -> -e(1)-e(2)-e(3)
-1 -2 0 -3 -> -e(1)-2*e(2)-3*e(4)
        -1 -> -e(1)     

Visual Basic .NET

Translation of: C#

<lang vbnet>Imports System.Text

Module Module1

   Function LinearCombo(c As List(Of Integer)) As String
       Dim sb As New StringBuilder
       For i = 0 To c.Count - 1
           Dim n = c(i)
           If n < 0 Then
               If sb.Length = 0 Then
                   sb.Append("-")
               Else
                   sb.Append(" - ")
               End If
           ElseIf n > 0 Then
               If sb.Length <> 0 Then
                   sb.Append(" + ")
               End If
           Else
               Continue For
           End If
           Dim av = Math.Abs(n)
           If av <> 1 Then
               sb.AppendFormat("{0}*", av)
           End If
           sb.AppendFormat("e({0})", i + 1)
       Next
       If sb.Length = 0 Then
           sb.Append("0")
       End If
       Return sb.ToString()
   End Function
   Sub Main()
       Dim combos = New List(Of List(Of Integer)) From {
           New List(Of Integer) From {1, 2, 3},
           New List(Of Integer) From {0, 1, 2, 3},
           New List(Of Integer) From {1, 0, 3, 4},
           New List(Of Integer) From {1, 2, 0},
           New List(Of Integer) From {0, 0, 0},
           New List(Of Integer) From {0},
           New List(Of Integer) From {1, 1, 1},
           New List(Of Integer) From {-1, -1, -1},
           New List(Of Integer) From {-1, -2, 0, -3},
           New List(Of Integer) From {-1}
       }
       For Each c In combos
           Dim arr = "[" + String.Join(", ", c) + "]"
           Console.WriteLine("{0,15} -> {1}", arr, LinearCombo(c))
       Next
   End Sub

End Module</lang>

Output:
      [1, 2, 3] -> e(1) + 2*e(2) + 3*e(3)
   [0, 1, 2, 3] -> e(2) + 2*e(3) + 3*e(4)
   [1, 0, 3, 4] -> e(1) + 3*e(3) + 4*e(4)
      [1, 2, 0] -> e(1) + 2*e(2)
      [0, 0, 0] -> 0
            [0] -> 0
      [1, 1, 1] -> e(1) + e(2) + e(3)
   [-1, -1, -1] -> -e(1) - e(2) - e(3)
[-1, -2, 0, -3] -> -e(1) - 2*e(2) - 3*e(4)
           [-1] -> -e(1)

Wren

Translation of: Kotlin
Library: Wren-fmt

<lang ecmascript>import "/fmt" for Fmt

var linearCombo = Fn.new { |c|

   var sb = ""
   var i = 0
   for (n in c) {
       if (n != 0) {
           var op = (n < 0 && sb == "") ? "-"   :
                    (n < 0)             ? " - " :
                    (n > 0 && sb == "") ? ""    : " + "
           var av = n.abs
           var coeff = (av == 1) ? "" : "%(av)*"
           sb = sb + "%(op)%(coeff)e(%(i + 1))"
       }
       i = i + 1
   }
   return (sb == "") ? "0" : sb

}

var combos = [

   [1, 2, 3],
   [0, 1, 2, 3],
   [1, 0, 3, 4],
   [1, 2, 0],
   [0, 0, 0],
   [0],
   [1, 1, 1],
   [-1, -1, -1],
   [-1, -2, 0, -3],
   [-1]

] for (c in combos) {

   Fmt.print("$-15s  ->  $s", c.toString, linearCombo.call(c))

}</lang>

Output:
[1, 2, 3]        ->  e(1) + 2*e(2) + 3*e(3)
[0, 1, 2, 3]     ->  e(2) + 2*e(3) + 3*e(4)
[1, 0, 3, 4]     ->  e(1) + 3*e(3) + 4*e(4)
[1, 2, 0]        ->  e(1) + 2*e(2)
[0, 0, 0]        ->  0
[0]              ->  0
[1, 1, 1]        ->  e(1) + e(2) + e(3)
[-1, -1, -1]     ->  -e(1) - e(2) - e(3)
[-1, -2, 0, -3]  ->  -e(1) - 2*e(2) - 3*e(4)
[-1]             ->  -e(1)

zkl

Translation of: Raku

<lang zkl>fcn linearCombination(coeffs){

  [1..].zipWith(fcn(n,c){ if(c==0) "" else "%s*e(%s)".fmt(c,n) },coeffs)
     .filter().concat("+").replace("+-","-").replace("1*","")
  or 0

}</lang> <lang zkl>T(T(1,2,3),T(0,1,2,3),T(1,0,3,4),T(1,2,0),T(0,0,0),T(0),T(1,1,1),T(-1,-1,-1),

 T(-1,-2,0,-3),T(-1),T)

.pump(Console.println,linearCombination);</lang>

Output:
e(1)+2*e(2)+3*e(3)
e(2)+2*e(3)+3*e(4)
e(1)+3*e(3)+4*e(4)
e(1)+2*e(2)
0
0
e(1)+e(2)+e(3)
-e(1)-e(2)-e(3)
-e(1)-2*e(2)-3*e(4)
-e(1)
0